Here you'll find documentation related to the Sinch Python SDK, including how to install it, initialize it, and start developing Python code using Sinch services.
To use Sinch services, you'll need a Sinch account and access keys. You can sign up for an account and create access keys at dashboard.sinch.com.
For more information on the SDK, refer to the dedicated Python SDK documentation section, and for the Sinch APIs on which this SDK is based, refer to the official developer documentation portal.
- Prerequisites
- Installation
- Supported APIs
- Getting started
- Logging
- Handling Exceptions
- Custom HTTP client implementation
- Third-party dependencies
- Examples
- Changelog and Migration
- License
- Contact
Warning: This SDK is intended for server-side (backend) use only. Do not use it in front-end or client-side applications (web, mobile, or desktop), regardless of language or framework. Doing so can expose your Sinch credentials to end-users.
Run the following command to install the SDK:
pip install sinch| API Category | API Name |
|---|---|
| Messaging | Conversation API |
| SMS API | |
| Numbers | Numbers API |
| Verification | Number Lookup API |
Note: The SMS API is end-of-sale. New integrations should use the Conversation API instead, which supports SMS and many other channels.
To start using the SDK, initialize the main client class. This client gives you access to all the SDK services:
import os
from sinch import SinchClient
# Warning: not all APIs support project authentication. Check the section for each API before using this snippet.
sinch_client = SinchClient(
project_id=os.environ["SINCH_PROJECT_ID"],
key_id=os.environ["SINCH_KEY_ID"],
key_secret=os.environ["SINCH_KEY_SECRET"],
)Get project_id, key_id and key_secret from the Access keys page in your Sinch dashboard (key_secret is shown only once, at creation time). It's highly recommended to not hardcode these credentials: load them from environment variables for local development, and from a secret manager in production.
This snippet is the common starting point for every API. Some APIs have a different initialization or need extra parameters (for example, a region), see the section for each API.
The Conversation API is regionalized. To use this API, the conversation_region parameter is required:
sinch_client = SinchClient(
project_id=os.environ["SINCH_PROJECT_ID"],
key_id=os.environ["SINCH_KEY_ID"],
key_secret=os.environ["SINCH_KEY_SECRET"],
conversation_region="eu",
)The Conversation API delivers asynchronous Sinch Events to the Event Destination URL you configure for your app in the Conversation dashboard. validate_authentication_header confirms a request comes from Sinch and parse_event turns its payload into a typed event object; headers and raw_body are the incoming request's headers and raw body:
sinch_events = sinch_client.conversation.sinch_events(SINCH_EVENT_SECRET)
is_valid = sinch_events.validate_authentication_header(headers=headers, json_payload=raw_body)
event = sinch_events.parse_event(raw_body, headers)SINCH_EVENT_SECRET is optional and set per app in the Conversation dashboard. parse_event works without validating the request, but then its origin can't be verified, so calling validate_authentication_header (which returns True/False) is recommended in production.
You can find a complete example in examples/sinch_events/conversation_api.
Warning: the SMS API is end-of-sale. For new integrations, prefer the Conversation API.
The SMS API is regionalized: set sms_region to the region where your SMS account is hosted. The accepted values are us, eu, au, br and ca, and the region also determines which credentials you can use:
- Project access keys — available only in the
usandeuregions. Use the sameproject_id,key_idandkey_secretas the common client, plussms_region:
sinch_client = SinchClient(
project_id=os.environ["SINCH_PROJECT_ID"],
key_id=os.environ["SINCH_KEY_ID"],
key_secret=os.environ["SINCH_KEY_SECRET"],
sms_region="us",
)SMS authentication for new projects
Projects created after the SMS API end-of-sale (
15/04/26) cannot use project access keys — the SMS API requests return401 Unauthorized.If you encounter this issue, consider the following options:
- Use service plan credentials (
service_plan_id+sms_api_token)- Use the Conversation API, which works with project access keys.
- Contact your account manager
- Service plan — available in all regions (
us,eu,au,br,ca). Use aservice_plan_idandsms_api_token, both available on the Service APIs dashboard:
sinch_client = SinchClient(
service_plan_id=os.environ["SINCH_SERVICE_PLAN_ID"],
sms_api_token=os.environ["SINCH_SMS_API_TOKEN"],
sms_region="us",
)Note: if you use both the SMS and the Conversation API from the same client, set
sms_regionandconversation_regionto the same region. Mismatched regions cause delivery failures.
The SMS API delivers asynchronous Sinch Events to an Event Destination, whose URL is set per batch with the event_destination_target parameter on the send, update and replace operations (for example sinch_client.sms.batches.send_sms). validate_authentication_header confirms a request comes from Sinch and parse_event turns its payload into a typed event object; headers and raw_body are the incoming request's headers and raw body:
sinch_events = sinch_client.sms.sinch_events(SINCH_EVENT_SECRET)
is_valid = sinch_events.validate_authentication_header(headers=headers, json_payload=raw_body)
event = sinch_events.parse_event(raw_body, headers)Signature authentication for SMS events must be enabled for your account by your account manager; until then the signature headers are absent and parse_event can be used on its own. See the SMS events documentation.
You can find a complete example in examples/sinch_events/sms_api.
The Numbers API needs no extra parameters, use the common client based in project authentication shown above.
The Numbers API delivers asynchronous Sinch Events to the Event Destination you configure through sinch_client.numbers.event_destinations. validate_authentication_header confirms a request comes from Sinch and parse_event turns its payload into a typed event object; headers and raw_body are the incoming request's headers and raw body:
sinch_events = sinch_client.numbers.sinch_events(SINCH_EVENT_SECRET)
is_valid = sinch_events.validate_authentication_header(headers=headers, json_payload=raw_body)
event = sinch_events.parse_event(raw_body, headers)SINCH_EVENT_SECRET is the value configured on the Event Destination. parse_event works without validating the request, but then its origin can't be verified, so calling validate_authentication_header is recommended in production.
You can find a complete example in examples/sinch_events/numbers_api.
The Number Lookup API needs no extra parameters, use the common client based in project authentication shown above.
Once your client is configured, you can send your first message. The example below uses the Conversation API to send a simple text message over SMS. Replace CONVERSATION_APP_ID with your app ID and RECIPIENT_PHONE_NUMBER with the recipient's phone number:
response = sinch_client.conversation.messages.send(
app_id="CONVERSATION_APP_ID",
message={
"text_message": {
"text": "[Python SDK: Conversation Message] Sample text message",
},
},
recipient_identities=[
{
"channel": "SMS",
"identity": "RECIPIENT_PHONE_NUMBER",
}
],
)
print(f"Successfully sent message.\n{response}")Logging configuration for this SDK utilizes following hierarchy:
- If no configuration was provided via
logger_nameorloggerconfigurable, SDK will inherit configuration from the root logger with theSinchprefix. - If
logger_nameconfigurable was provided, SDK will use logger related to that name. For example:myapp.sinchwill inherit configuration from themyapplogger. - If
logger(logger instance) configurable was provided, SDK will use that particular logger for all its logging operations.
If all logging returned by this SDK needs to be disabled, usage of NullHandler provided by the standard logging module is advised.
Each API throws a custom, API related exception for an unsuccessful backed call.
Example for Numbers API:
from sinch.domains.numbers.api.v1.exceptions import NumbersException
try:
paginator = sinch_client.numbers.list(
region_code="US",
number_type="LOCAL",
)
except NumbersException as err:
passFor handling all possible exceptions thrown by this SDK use SinchException (superclass of all Sinch exceptions) from sinch.core.exceptions.
By default, the HTTP implementation uses the requests library.
To use a custom HTTP client, assign your transport to the client's configuration after initialization.
Custom transports must extend HTTPTransport and implement the send method. The base class provides prepare_request and authenticate helpers, and handles OAuth token refresh automatically.
The following example replaces the default requests backend with httpx and routes traffic through an authenticated proxy:
import httpx
from sinch import SinchClient
from sinch.core.ports.http_transport import HTTPTransport
from sinch.core.endpoint import HTTPEndpoint
from sinch.core.models.http_response import HTTPResponse
class MyHTTPImplementation(HTTPTransport):
def __init__(self, sinch, proxy_url, proxy_user, proxy_password):
super().__init__(sinch)
self.http_client = httpx.Client(
proxy=f"http://{proxy_user}:{proxy_password}@{proxy_url}"
)
def send(self, endpoint: HTTPEndpoint) -> HTTPResponse:
request_data = self.prepare_request(endpoint)
request_data = self.authenticate(endpoint, request_data)
body = request_data.request_body
response = self.http_client.request(
method=request_data.http_method,
url=request_data.url,
json=body if isinstance(body, dict) else None,
content=body if not isinstance(body, dict) else None,
auth=request_data.auth,
headers=request_data.headers,
params=request_data.query_params,
timeout=self.sinch.configuration.connection_timeout,
)
response_body = self.deserialize_json_response(response)
return HTTPResponse(
status_code=response.status_code,
body=response_body,
headers=dict(response.headers),
)
sinch_client = SinchClient(
key_id="key_id",
key_secret="key_secret",
project_id="some_project",
)
sinch_client.configuration.transport = MyHTTPImplementation(
sinch_client,
proxy_url="proxy.example.com:8080",
proxy_user="proxy_user",
proxy_password="proxy_password",
)Note: Asynchronous HTTP clients are not supported. The transport must be a synchronous implementation.
The SDK relies on the following third-party dependencies:
- requests: HTTP client used as the default transport for all API calls.
- pydantic: Data validation and serialization for request and response models.
You can find:
- a Python example of each request in the examples/snippets folder.
- getting started guides for specific use cases in the examples/getting-started folder.
- server-side event handling examples in the examples/sinch_events folder.
For information about the latest changes in the SDK, please refer to the CHANGELOG file and the MIGRATION_GUIDE for instructions on how to update your code when upgrading to a new major version of the SDK.
This project is licensed under the Apache License.
See the LICENSE file for the license text.
Developer Experience engineering team: team-developer-experience@sinch.com