Everything you need to build messaging
Three building blocks, one consistent API and SDK surface.
Send and receive SMS worldwide with a single REST call. Delivery reports, sender IDs and unicode included.
Turn any Android device into an SMS gateway. Route messages through your own SIMs with local rates.
Subscribe to inbound messages and delivery events with signed, retried webhook deliveries.
From zero to first message
Four steps to a working integration.
- 1Create an API key
Sign in to the Msgly dashboard and generate a secret API key.
- 2Install an SDK
Add the official Msgly SDK for your language, or call the REST API directly.
- 3Send your first message
Make a single POST request to /v1/messages and watch it arrive.
- 4Receive webhooks
Point a public endpoint at Msgly to handle inbound SMS and delivery events.
- Node.js
- Python
- Java
- Go
- PHP
- C#
npm install @msgly/sdk
pip install msgly
implementation "live.msgly:msgly-java:1.0.0"
go get gitlab.com/msgly/msgly-go
composer require msgly/msgly-php
dotnet add package Msgly
Send a message. Receive a webhook.
Pick your language once β every sample stays in sync.
Send an SMS
- cURL
- Node.js
- Python
- Java
- Kotlin
- PHP
- Go
- C#
curl https://api.msgly.live/v1/messages \
-H "Authorization: Bearer $MSGLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+48512345678",
"from": "Msgly",
"text": "Your Msgly code is 4921"
}'
import { Msgly } from '@msgly/sdk';
const msgly = new Msgly({ apiKey: process.env.MSGLY_API_KEY });
const message = await msgly.messages.send({
to: '+48512345678',
from: 'Msgly',
text: 'Your Msgly code is 4921',
});
console.log(message.id, message.status);
import os
from msgly import Msgly
client = Msgly(api_key=os.environ["MSGLY_API_KEY"])
message = client.messages.send(
to="+48512345678",
sender="Msgly",
text="Your Msgly code is 4921",
)
print(message.id, message.status)
import live.msgly.Msgly;
import live.msgly.model.Message;
Msgly msgly = Msgly.builder()
.apiKey(System.getenv("MSGLY_API_KEY"))
.build();
Message message = msgly.messages().send(
Message.request()
.to("+48512345678")
.from("Msgly")
.text("Your Msgly code is 4921")
.build());
System.out.println(message.id() + " " + message.status());
import live.msgly.Msgly
import live.msgly.model.MessageRequest
val msgly = Msgly(apiKey = System.getenv("MSGLY_API_KEY"))
val message = msgly.messages.send(
MessageRequest(
to = "+48512345678",
from = "Msgly",
text = "Your Msgly code is 4921",
),
)
println("${message.id} ${message.status}")
<?php
use Msgly\Client;
$msgly = new Client(getenv('MSGLY_API_KEY'));
$message = $msgly->messages->send([
'to' => '+48512345678',
'from' => 'Msgly',
'text' => 'Your Msgly code is 4921',
]);
echo $message->id, ' ', $message->status;
package main
import (
"context"
"fmt"
"os"
"gitlab.com/msgly/msgly-go"
)
func main() {
client := msgly.NewClient(os.Getenv("MSGLY_API_KEY"))
message, err := client.Messages.Send(context.Background(), &msgly.MessageRequest{
To: "+48512345678",
From: "Msgly",
Text: "Your Msgly code is 4921",
})
if err != nil {
panic(err)
}
fmt.Println(message.ID, message.Status)
}
using Msgly;
var client = new MsglyClient(Environment.GetEnvironmentVariable("MSGLY_API_KEY"));
var message = await client.Messages.SendAsync(new MessageRequest
{
To = "+48512345678",
From = "Msgly",
Text = "Your Msgly code is 4921",
});
Console.WriteLine($"{message.Id} {message.Status}");
Receive a webhook
- Node.js
- Python
- Java
- Kotlin
- PHP
- Go
- C#
import express from 'express';
import { Msgly } from '@msgly/sdk';
const app = express();
const msgly = new Msgly({ apiKey: process.env.MSGLY_API_KEY });
app.post('/webhooks/msgly', express.raw({ type: '*/*' }), (req, res) => {
const event = msgly.webhooks.verify(
req.body,
req.header('X-Msgly-Signature'),
process.env.MSGLY_WEBHOOK_SECRET,
);
if (event.type === 'message.received') {
console.log('Inbound SMS from', event.data.from, ':', event.data.text);
}
res.sendStatus(200);
});
app.listen(3000);
import os
from flask import Flask, request
from msgly import Msgly
app = Flask(__name__)
client = Msgly(api_key=os.environ["MSGLY_API_KEY"])
@app.post("/webhooks/msgly")
def handle():
event = client.webhooks.verify(
request.data,
request.headers.get("X-Msgly-Signature"),
os.environ["MSGLY_WEBHOOK_SECRET"],
)
if event.type == "message.received":
print("Inbound SMS from", event.data.sender, ":", event.data.text)
return "", 200
@PostMapping("/webhooks/msgly")
public ResponseEntity<Void> handle(
@RequestBody byte[] payload,
@RequestHeader("X-Msgly-Signature") String signature) {
MsglyEvent event = Msgly.webhooks().verify(
payload, signature, System.getenv("MSGLY_WEBHOOK_SECRET"));
if ("message.received".equals(event.type())) {
log.info("Inbound SMS from {}: {}", event.data().from(), event.data().text());
}
return ResponseEntity.ok().build();
}
post("/webhooks/msgly") {
val payload = call.receiveText()
val signature = call.request.header("X-Msgly-Signature")
val event = Msgly.webhooks.verify(
payload,
signature,
System.getenv("MSGLY_WEBHOOK_SECRET"),
)
if (event.type == "message.received") {
println("Inbound SMS from ${event.data.from}: ${event.data.text}")
}
call.respond(HttpStatusCode.OK)
}
<?php
use Msgly\Webhook;
$event = Webhook::verify(
file_get_contents('php://input'),
$_SERVER['HTTP_X_MSGLY_SIGNATURE'] ?? '',
getenv('MSGLY_WEBHOOK_SECRET'),
);
if ($event->type === 'message.received') {
error_log("Inbound SMS from {$event->data->from}: {$event->data->text}");
}
http_response_code(200);
package main
import (
"io"
"log"
"net/http"
"os"
"gitlab.com/msgly/msgly-go"
)
func handler(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
event, err := msgly.VerifyWebhook(
body,
r.Header.Get("X-Msgly-Signature"),
os.Getenv("MSGLY_WEBHOOK_SECRET"),
)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if event.Type == "message.received" {
log.Printf("Inbound SMS from %s: %s", event.Data.From, event.Data.Text)
}
w.WriteHeader(http.StatusOK)
}
app.MapPost("/webhooks/msgly", async (HttpRequest req) =>
{
using var reader = new StreamReader(req.Body);
var payload = await reader.ReadToEndAsync();
var evt = MsglyWebhook.Verify(
payload,
req.Headers["X-Msgly-Signature"],
Environment.GetEnvironmentVariable("MSGLY_WEBHOOK_SECRET"));
if (evt.Type == "message.received")
Console.WriteLine($"Inbound SMS from {evt.Data.From}: {evt.Data.Text}");
return Results.Ok();
});
Platform status
Live availability of Msgly services.