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.

Base URL
https://unismsapi.com/api
Authentication

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.

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!"}'

Endpoints

GET /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

pending unregistered inactive active

Response Codes

200 OK 401 Unauthorized 404 Not Found
POST /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

pending sent failed received

Response Codes

201 Created 401 Unauthorized 422 Unprocessable Entity 429 Too Many Requests

A 429 Too Many Requests response includes an x-retry-after-ms header indicating how long to wait before retrying.

GET /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

200 OK 401 Unauthorized 404 Not Found
GET /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

200 OK 401 Unauthorized 404 Not Found

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!"}'