Official Sinch API skills for AI coding agents — SMS, Voice, Verification, Numbers, Mailgun email, and more.
71
89%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
You can include Sinch in several ways. Pick the one that fits your setup.
Host the library with your site and include it:
<script src="sinch.min.js"></script><script src="https://cdn.sinch.com/latest/sinch-rtc-min.js"></script>Every integration must follow these steps in order. Do not skip or reorder them.
SinchClientListener to handle onClientStarted, onClientFailed, and onCredentialsRequired.onCredentialsRequired to supply a signed JWT. Decide whether to sign client-side (prototyping only) or fetch from a backend.sinchClient.setSupportManagedPush() before start(). Provide a service worker (sw.js) that forwards push payloads to open tabs. Required for app-to-app calls, even as the caller.sinchClient.start(). Wait for onClientStarted before proceeding.sinchClient.callClient to detect incoming calls via onIncomingCall.CallListener to handle onCallProgressing, onCallRinging, onCallAnswered, onCallEstablished, and onCallEnded.When helping a user integrate, walk through these steps one at a time. Confirm each step is in place before moving to the next.
The SinchClient is the Sinch SDK entry point. It's used to configure the user’s and device’s capabilities, as well as to provide access to feature classes such as the CallController, AudioController, and VideoController.
const sinchClient = Sinch.getSinchClientBuilder()
.applicationKey("<application key>")
.environmentHost("ocra.api.sinch.com")
.userId("<user id>")
.build();ocra.api.sinch.com is the name of the Sinch API that SDK clients target.Before starting, add a client listener (see SinchClientListener reference):
sinchClient.addListener({
onClientStarted: (client) => {
// sinch client started successfully
},
onClientFailed: (client, error) => {
// sinch client start failed
},
onCredentialsRequired: (client, clientRegistration) => {
// registration required, get jwt token for user and register
}
});
sinchClient.start();When SinchClient starts with a given user ID, you must provide an authorization token (JWT) to register with Sinch.
Implement SinchClientListener.onCredentialsRequired() and supply a JWT signed with the Application Secret.
Read https://developers.sinch.com/docs/in-app-calling/js/application-authentication.md
For production application it is recommended to generate and sign the JWT token on the backend server, then send it over a secure channel to the application and Sinch client running on the device.
Ask the user whether it can be embedded.
If it can be embedded:
A sample JWT helper is provided at assets/jwt-helper.js. Read and adapt it.
onCredentialsRequired(sinchClient, clientRegistration) {
try {
const jwt = new JWT(CONFIG.applicationKey, CONFIG.applicationSecret, this.userId);
const token = await jwt.toJwt();
clientRegistration.register(token);
} catch (error) {
console.log('Authentication failed: ' + error.message);
clientRegistration.registerFailed();
}
}If it can not be embedded: Implement the required functionality on your backend and fetch a signed registration token when required.
onCredentialsRequired: (sinchClient, clientRegistration) => {
yourAuthServer
.getRegistrationToken(sinchClient.userId)
.then((token) => {
clientRegistration.register(token);
})
.catch(() => {
clientRegistration.registerFailed();
});
};To receive incoming calls in the browser via W3C Web Push API, enable managed push:
// Enable managed push with the default Service Worker path (sw.js)
sinchClient.setSupportManagedPush();By default, Sinch expects a Service Worker file at sw.js in your current directory.
If you use a custom path or filename, pass it explicitly:
sinchClient.setSupportManagedPush("<path_to_serviceworker>");Add a basic Service Worker that forwards push payloads to open tabs.
This lets SinchClient process the payload and trigger CallClientListener.onIncomingCall when a new call arrives.
// sw.js (basic example)
self.addEventListener("push", (event) => {
const body = event.data?.json?.() ?? null;
event.waitUntil(
self.clients
.matchAll({ includeUncontrolled: true, type: "window" })
.then((clients) => {
clients.forEach((client) => {
client.postMessage({
visible: client.visibilityState === "visible",
data: body,
});
});
})
);
});For a more advanced sw.js that handles mobile browser limitations, see the reference app:
voicecall/sw.js
When managed push is enabled and your Service Worker forwards messages as above, incoming calls will be delivered to onIncomingCall in CallClientListener.
Note:
For use cases requiring only outgoing App-to-Phone, App-to-SIP, or App-to-Conference calls, calling sinchClient.setSupportManagedPush is not required. You can place these calls directly once the Sinch client is started.
The Sinch SDK supports four types of calls: app-to-app (audio or video), app-to-phone, app-to-sip and conference calls. The CallClient is the entry point for the calling functionality of the Sinch SDK.
Calls are placed through the CallClient and events are received using the CallClientListener. The call client is owned by the SinchClient and accessed using sinchClient.callClient.
Use the CallClient.callUser() method so Sinch can connect the call to the callee.
var callClient = sinchClient.callClient;
var call = callClient.callUser('<remote user id>');
// Video call:
// var call = callClient.callUserVideo('<remote user id>');
call.addListener(...);The returned call object includes participant details, start time, state,and possible errors.
Assuming the callee’s device is available, CallListener.onCallProgressing() is invoked. If you play a progress tone, start it here. When the callee receives the call, CallListener.onCallRinging() fires. This indicates the callee’s device is ringing. When the other party answers, CallListener.onCallAnswered() is called. Stop any progress tone. Once full audio connectivity is established, CallListener.onCallEstablished() is emitted. Users can now talk.
Typically, connectivity is already established when the call is answered, so
onCallEstablished may follow immediately after onCallAnswered.
On poor networks, it can take longer—consider showing a “connecting”
indicator.
Important:
For App-to-App calls, you must enable managed push by calling sinchClient.setSupportManagedPush(), even if you are the caller. See the full setup in Push notifications.
An app-to-phone call is a call that's made to a phone on the regular telephone network. Setting up an app-to-phone call is not much different than setting up an app-to-app call. Instead of invoking the callUser method, invoke the CallClient.callPhoneNumber() method and pass an E.164 number prefixed with +. For example, to call the US phone number 415 555 0101, specify +14155550101. The + is the required prefix with the US country code 1 prepended to the local subscriber number.
Mandatory step! You must provide a CLI (Calling Line Identifier) or your call will fail. You need a number from Sinch so you can provide a valid CLI to the handset you are calling. Specify your CLI during building SinchClient by using callerIdentifier method.
Note: When your account is in trial mode, you can only call your verified numbers. If you want to call any number, you need to upgrade your account!
An app-to-sip call is a call that's made to a SIP server. Setting up an app-to-sip call is not much different from setting up an app-to-app call. Instead of invoking the callUser method, invoke CallClient.callSip(). The SIP identity should be in the form user@server. By convention, when passing custom headers in the SIP call, the headers should be prefixed with x-. If the SIP server reports any errors, the CallDetails object will provide an error with the SIP error type.
A conference call can be made to connect a user to a conference room where multiple users can be connected at the same time. The identifier for a conference room may not be longer than 64 characters.
var callClient = sinchClient.callClient;
var call = callClient.callConference('<conferenceId>');
call.addListener(...);To select a specific audio input device, set the deviceId constraint via
CallClient.setAudioTrackConstraints().
sinchClient.callClient.setAudioTrackConstraints({
deviceId: { exact: <yourAudioDeviceId> },
});For a full sample of input/output device selection, see the reference app.
To answer calls, the application must be notified when the user receives an incoming call.
Add a CallClientListener to CallClient to act on incoming calls. When a call arrives, CallClientListener.onIncomingCall() is executed.
var callClient = sinchClient.callClient;
callClient.addListener(...);When the incoming call method is executed, the call can either be connected automatically without any user action, or it can wait for the user to press the answer or the hangup button. If the call is set up to wait for a user response, we recommended that a ringtone is played to notify the user that there is an incoming call.
onIncomingCall = (callClient, call) => {
// Start playing ringing tone
...
// Add call listener
call.addListener(...);
}To get events related to the call, add a call listener. The call object contains details about participants, start time, potential error codes, and error messages.
The Sinch SDK supports receiving incoming calls that originate from the PSTN (regular phone network) or from SIP endpoints.
When a call arrives at a Sinch voice number or via SIP origination, the Sinch platform triggers an Incoming Call Event (ICE) callback to your backend.
Our platform can then route this call to an in-app user by responding with the connectMxp SVAML action.
When a PSTN or SIP call comes in, respond to the ICE callback with a connectMxp action to route the call to an app user:
{
"action": {
"name": "connectMxp",
"destination": {
"type": "username",
"endpoint": "target-user-id"
}
}
}When an incoming call is a video call, the CallClientListener.onIncomingCall() section for details on how to add video views.
To answer the call, use the Call.answer() method on the call to accept it. If a ringtone was previously played, it should be stopped now.
User presses the answer button:
// User answers the call
call.answer();
// Stop playing ringing toneIf the call shouldn't be answered, use Call.hangup() on the call to decline. The caller is notified that the incoming call was denied. If a ringtone was previously played, it should be stopped now.
User presses the hangup button:
// User doesn't want to answer
call.hangup();
// Stop playing ringing tone
...When the user wants to disconnect an ongoing call, use Call.hangup() method. Either user taking part in a call can disconnect it. Hanging up a call:
call.hangup();When either party disconnects a call, the application is notified using the call listener method CallListener.onCallEnded(). This allows the user interface to be updated, an alert tone to be played, or similar actions to occur.
A call can be disconnected before it has been completely established.
Hanging up a connecting call:
// Starts a call asynchronously
var call = callClient.callUser('<remote user id>');
// User changed his/her mind, let’s hangup
call.hangup();Set up video calls with the Sinch JavaScript Voice and Video SDK.
Video calls follow the same flow as audio calls. Use CallClient.callUserVideo() to start a video call with a specific user. You’ll receive the same callbacks as for audio: progressing, ringing, answered, and established. For lifecycle details, see Audio calling.
Once you have a Call, you can access two MediaStreams:
incomingStream — remote stream sent to your appoutgoingStream — your local stream sent to the other partyAccess them via Call.incomingStream and Call.outgoingStream.
Bind the appropriate stream to a <video> element by setting srcObject:
const videoElement = document.getElementById(`${direction}-video`);
videoElement.srcObject = call.incomingStream;Use Call.pauseVideo() to temporarily stop sending your local video (for privacy or to save bandwidth). Use Call.resumeVideo to start sending it again. Audio continues unless you mute it separately.
To select a specific camera, set the deviceId constraint via CallClient.setVideoTrackConstraints().
sinchClient.callClient.setVideoTrackConstraints({
deviceId: { exact: <yourVideoDeviceId> },
});For a full sample of input/output device selection, see the reference app.
skills
sinch-10dlc
references
sinch-authentication
sinch-conversation-api
sinch-elastic-sip-trunking
references
sinch-fax-api
sinch-imported-numbers-hosting-orders
references
sinch-in-app-calling
sinch-mailgun
references
sinch-mailgun-inspect
references
sinch-mailgun-optimize
references
sinch-mailgun-validate
sinch-number-lookup-api
sinch-number-order-api
sinch-numbers-api
references
sinch-porting-api
sinch-provisioning-api
sinch-sdks
sinch-verification-api