Virtual Numbers API
Simple SMS API for 2-way communication.
UniSMS Virtual Numbers let you send and receive SMS using a dedicated Philippine mobile number. This guide will help you integrate virtual number SMS functionality into your applications.
Virtual Numbers are limited and by requests. Please reach out to support to have your virtual number in your account.
https://unismsapi.com/api
All API requests require Basic Authentication using your API key. Use your API Secret key as the username and empty for the password.
API_SECRET_KEY:
Authorization: Basic Base64Encode(API_SECRET_KEY:)
(Most libraries automatically encode this to Base64)
Example code from a cUrl request.
Endpoints
/virtual_numbers/:id
Get Virtual Number Details
Retrieve the details of your virtual number including its status and subscription dates.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id |
string |
Your virtual number reference ID, returned as
message.virtual_number_id
when sending an SMS
|
Example Response
{
"virtual_number": {
"id": "vnum_6e4966d7-33f7-4922-8236-3db952d37be9",
"status": "active",
"created_at": "2026-03-01T00:00:00Z",
"expires_at": "2026-06-01T00:00:00Z",
"mobile_number": "+639123456789",
"deactivated_at": null
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
virtual_number.id |
string |
The reference ID of your virtual number |
virtual_number.mobile_number |
string |
Your virtual number in E.164 format |
virtual_number.status |
string |
The current status of your virtual number |
virtual_number.created_at |
string |
Timestamp when the virtual number subscription started (UTC) |
virtual_number.expires_at |
string |
Timestamp when the virtual number subscription expires (UTC) |
virtual_number.deactivated_at |
string |
Timestamp when the virtual number was deactivated, if any |
Virtual Number Statuses
Response Codes
/virtual_numbers/sms
Send SMS from Virtual Number
Send an SMS message from your virtual number to a recipient.
Your virtual number must be active and must belong to your account.
Messages containing links or URLs or OTPs are not allowed with virtual number SMS. If you wish to send these, you must use a sender id.
Request Body
{
"from": "+639123456789",
"content": "Hello from your virtual number!",
"to": "+639987654321"
}
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
from |
string |
Yes | Your active virtual number in E.164 format (e.g., +639123456789) |
to |
string |
Yes | Recipient phone number in E.164 format. Must be a valid Philippine number |
content |
string |
Yes | SMS message content. Links and URLs are not allowed |
Example Response
{
"message": {
"status": "pending",
"from": "+639123456789",
"content": "Hello from your virtual number!",
"to": "+639987654321",
"created": "2026-03-16T14:32:44Z",
"reference_id": "tmsg_8a27ce39-6546-49f8-a17a-707868b39288",
"virtual_number_id": "vnum_6e4966d7-33f7-4922-8236-3db952d37be9",
"txt_conversation_id": "tcon_fc33deda-584f-47fb-9d05-89eed191a586"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
message.from |
string |
The virtual number the SMS was sent from |
message.to |
string |
The recipient phone number |
message.content |
string |
The SMS message content |
message.status |
string |
The current message status (e.g., pending) |
message.created |
string |
Timestamp when the message was created (UTC) |
message.reference_id |
string |
Unique reference id for this message |
message.virtual_number_id |
string |
Unique id for your virtual number |
message.txt_conversation_id |
string |
Unique id for this conversation thread where this message belongs |
Message Statuses
Response Codes
A 429 Too Many Requests
response includes an x-retry-after-ms
header indicating how long to wait before retrying.
/virtual_numbers/sms/:reference_id
Get Message
Retrieve a single txt message sent from or received by your virtual number using its reference ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
reference_id |
string |
The message reference ID returned when sending an SMS |
Example Response
{
"message": {
"status": "pending",
"from": "+639123456789",
"content": "Hello from your virtual number!",
"to": "+639987654321",
"created": "2026-03-16T14:32:44Z",
"reference_id": "tmsg_8a27ce39-6546-49f8-a17a-707868b39288",
"virtual_number_id": "vnum_6e4966d7-33f7-4922-8236-3db952d37be9",
"txt_conversation_id": "tcon_fc33deda-584f-47fb-9d05-89eed191a586"
}
}
Response Codes
/virtual_numbers/sms/conversation/:txt_conversation_id
Get Conversation Messages
Retrieve all txt messages in a conversation between a recipient and your virtual number. Messages are returned newest first, up to 100 messages.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
txt_conversation_id |
string |
The conversation reference ID returned as
message.txt_conversation_id
when sending an SMS
|
Example Response
{
"id": "tcon_fc33deda-584f-47fb-9d05-89eed191a586",
"messages": [
{
"status": "received",
"from": "+639987654321",
"content": "Got it, thanks!",
"to": "+639123456789",
"created": "2026-03-16T14:35:10Z",
"reference_id": "tmsg_91b3d7fa-2341-4d9e-a55b-5f6e7c8d9e0f"
},
{
"status": "sent",
"from": "+639123456789",
"content": "Hello from your virtual number!",
"to": "+639987654321",
"created": "2026-03-16T14:32:44Z",
"reference_id": "tmsg_8a27ce39-6546-49f8-a17a-707868b39288"
}
],
"virtual_number_id": "vnum_6e4966d7-33f7-4922-8236-3db952d37be9"
}
Response Fields
| Field | Type | Description |
|---|---|---|
id |
string |
The conversation reference ID |
virtual_number_id |
string |
The reference ID of the virtual number in this conversation |
txt_messages |
array |
Array of txt message objects, newest first (up to 100) |
txt_messages[].from |
string |
The sender's phone number |
txt_messages[].to |
string |
The recipient phone number |
txt_messages[].content |
string |
The message content |
txt_messages[].status |
string |
The message status (e.g., sent, received) |
txt_messages[].created |
string |
Timestamp when the message was created (UTC) |
txt_messages[].reference_id |
string |
The message reference ID |
Response Codes
Webhooks
Incoming SMS
When someone sends an SMS to your virtual number, UniSMS will forward the incoming message to your webhook url by
sending a POST
request to your configured webhook URL. This lets you receive
and handle replies in real time without polling.
Configuring Incoming SMS Webhooks
Set your webhook URL in the Virtual Numbers: INCOMING
field to receive incoming SMS from your virtual number. Your URL must:
- Use HTTPS (secure endpoint)
- Be publicly accessible
- Accept POST requests
Event Types
| Event | Description |
|---|---|
txt.received |
Triggered when your virtual number receives an SMS |
Request Headers
| Header | Description |
|---|---|
Content-Type |
application/json |
Accept |
application/json |
webhook-id |
The unique ID of this webhook delivery |
webhook-secret-key |
Your webhook secret key, used to verify the delivery came from UniSMS |
Verifying Webhook Authenticity
Each delivery includes a webhook-secret-key
header. Compare it against the Webhook Secret Key
shown on the Webhooks
page to confirm the request is from UniSMS.
Payload Structure
All incoming SMS webhook payloads follow a consistent structure:
{
"id": "msg_84e8b93b-6315-46af-a686",
"message": {
"from": "+639987654321",
"content": "Hello!",
"to": "+639123456789",
"virtual_number_id": "vn_4a3f8b2c-9d1e-4f5a-8b7c-2d6e0a1b3c4d",
"txt_conversation_id": "tcon_7ef5f85e-1f2e-4a8a-9f43-483c8beb93bb"
},
"event": "txt.received"
}
Payload Fields
| Field | Type | Description |
|---|---|---|
event |
string |
The event type ("txt.received") |
id |
string |
The reference ID of the incoming txt message |
message.from |
string |
The sender's phone number in E.164 format |
message.to |
string |
Your virtual number in E.164 format |
message.content |
string |
The message content sent by the sender |
message.reference_id |
string |
The reference ID of your virtual number |
message.txt_conversation_id |
string |
Unique id for this conversation thread where this message belongs |
Acknowledging Webhooks
Respond to the webhook with a 200 OK status to acknowledge receipt.
If your endpoint does not return a 2xx status, we will retry the delivery
up to 3 attempts. Every delivery attempt is recorded in the dashboard under Webhooks.
Sample Codes
Here you'll find a collection of sample codes to help you create your first virtual number SMS request.
cURL
curl -X POST https://unismsapi.com/api/virtual_numbers/sms \
-u YOUR_SECRET_KEY: \
-H "Content-Type: application/json" \
-d '{"from": "+639123456789", "to": "+639987654321", "content": "Hello from your virtual number!"}'
Node.js
const axios = require('axios');
const response = await axios.post('https://unismsapi.com/api/virtual_numbers/sms', {
from: '+639123456789',
to: '+639987654321',
content: 'Hello from your virtual number!'
}, {
auth: {
username: 'YOUR_SECRET_KEY',
password: ''
},
headers: {
'Content-Type': 'application/json'
}
});
console.log(response.data);
Python
import requests
from requests.auth import HTTPBasicAuth
response = requests.post(
'https://unismsapi.com/api/virtual_numbers/sms',
json={
'from': '+639123456789',
'to': '+639987654321',
'content': 'Hello from your virtual number!'
},
auth=HTTPBasicAuth('YOUR_SECRET_KEY', ''),
headers={
'Content-Type': 'application/json'
}
)
print(response.json())
PHP
<?php
$client = new GuzzleHttp\Client();
$response = $client->post('https://unismsapi.com/api/virtual_numbers/sms', [
'json' => [
'from' => '+639123456789',
'to' => '+639987654321',
'content' => 'Hello from your virtual number!'
],
'auth' => [
'YOUR_SECRET_KEY',
''
],
'headers' => [
'Content-Type' => 'application/json'
]
]);
echo $response->getBody();
Ruby
require 'httparty'
response = HTTParty.post(
'https://unismsapi.com/api/virtual_numbers/sms',
body: {
from: '+639123456789',
to: '+639987654321',
content: 'Hello from your virtual number!'
}.to_json,
basic_auth: [
'YOUR_SECRET_KEY',
''
],
headers: {
'Content-Type' => 'application/json'
}
)
puts response.body
C#
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Net;
var client = new HttpClient();
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes("YOUR_SECRET_KEY:"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
var content = new StringContent(
JsonSerializer.Serialize(new {
from = "+639123456789",
to = "+639987654321",
content = "Hello from your virtual number!"
}),
Encoding.UTF8,
"application/json"
);
var response = await client.PostAsync("https://unismsapi.com/api/virtual_numbers/sms", content);
Console.WriteLine(await response.Content.ReadAsStringAsync());
VB.NET
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Imports System.Net
Module SendVirtualNumberSms
Async Function Main() As Task
Dim client As New HttpClient()
Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes("YOUR_SECRET_KEY:"))
client.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Basic", credentials)
Dim jsonData = JsonSerializer.Serialize(New With {
.from = "+639123456789",
.to = "+639987654321",
.content = "Hello from your virtual number!"
})
Dim content As New StringContent(jsonData, Encoding.UTF8, "application/json")
Dim response = Await client.PostAsync("https://unismsapi.com/api/virtual_numbers/sms", content)
Console.WriteLine(Await response.Content.ReadAsStringAsync())
End Function
End Module
Java
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.io.OutputStream;
public class SendVirtualNumberSms {
public static void main(String[] args) throws Exception {
URL url = new URL("https://unismsapi.com/api/virtual_numbers/sms");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String auth = "YOUR_SECRET_KEY:";
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
conn.setRequestProperty("Authorization", "Basic " + encodedAuth);
conn.setDoOutput(true);
String jsonBody = "{\"from\": \"+639123456789\", \"to\": \"+639987654321\", \"content\": \"Hello from your virtual number!\"}";
try (OutputStream os = conn.getOutputStream()) {
os.write(jsonBody.getBytes(StandardCharsets.UTF_8));
}
int responseCode = conn.getResponseCode();
System.out.println("Response Code: " + responseCode);
}
}
Quick Start
Get your API key from the dashboard, then make your first virtual number SMS request:
curl -X POST https://unismsapi.com/api/virtual_numbers/sms \
-u your_api_key: \
-H "Content-Type: application/json" \
-d '{"from": "+639123456789", "to": "+639987654321", "content": "Hello from your virtual number!"}'