NAME
WWW::Vonage::API
VERSION
version 0.001
SYNOPSIS
use WWW::Vonage::API;
my $vonage = WWW::Vonage::API->new(
API_Key => 'ABC12345...',
API_Secret => '1234567...'
);
## Send an SMS
my $payload = {
to => '+6725550002',
from => '+6725550001',
channel => "sms",
message_type => "text",
text => 'There is a storm coming!',
};
my $response = $vonage->POST( 'Messages', $payload );
print $response->{content};
DESCRIPTION
WWW::Vonage::API aims to make connecting to and making REST calls on the Vonage API easy, reliable, and enjoyable.
NAME
WWW::Vonage::API - Accessing Vonage's REST API with Perl
Vonage API
The Vonage API documentation is found here: https://developer.vonage.com/en/home
The Vonage Communications API is a cloud-based platform that allows developers to embed programmable communication channels—like SMS, voice, video, and social messaging—directly into their applications, websites, and business systems.
Core API Offerings
The ecosystem is generally categorized into the following core products:
- 1. Messaging APIs
-
Includes the Messages API (multi-channel support for SMS, WhatsApp, etc.) and the dedicated SMS API.
- 2. Voice and Video APIs
-
Voice API for programmatically controlling phone calls and Video API (formerly Tokbox) for interactive video sessions.
- 3. Verify (Identity & Security)
-
A specialized tool for Two-Factor Authentication (2FA) that manages the entire verification workflow.
- 4. Identity & Network Insights
-
Includes Identity Insights and Number Insight API for fraud prevention and number validation.
- 5. Management and Enablement APIs
-
Helper APIs for managing accounts, purchasing numbers, and auditing usage.
Domain Host Version
In true large corporation fashion, not all Vonage APIs share the same domain or versioning scheme.
API Endpoint Mapping
+--------------------+----------------------+---------+
| API Name | Domain/Host | Version |
+--------------------+----------------------+---------+
| Account API | rest.nexmo.com | none |
| Application API | api.nexmo.com | v2 |
| Messages API | api.nexmo.com | v1 |
| Number Insight API | api.nexmo.com | none |
| Numbers API | rest.nexmo.com | none |
| Pricing API | api.nexmo.com | v2 |
| Redact API | api.nexmo.com | v1 |
| Reports API | api.nexmo.com | v2 |
| SMS API | rest.nexmo.com | none |
| Verify API | api.nexmo.com | v2 |
| Video API | video.api.vonage.com | v2 |
| Voice API | api.nexmo.com | v1 |
+--------------------+----------------------+---------+
As well some of the domains that start with 'api' are also available with a region specific domain and within some of the APIs you can have more than one version of an API call and version may vary by API call. Finally some APIs do not use or have a version number.
Using WWW::Vonage::API
In theory, all features should work with this module. However, some features require JSON Web Tokens (JWT). At this time, only **Basic Authentication** (API Key and Secret) is implemented.
- 1. Basic Call
-
my $payload = { to => '+6725550002', from => '+6725550001', channel => "sms", message_type => "text", text => 'There is a storm coming!', }; my $response = $vonage->POST( 'Messages',$payload );
In the above example the "Messages" API is being invoked following the Vonage API documentation (https://developer.vonage.com/en/api/messages?source=messages) For context a snippet of the documentation follows;
Available Operations:
Post Send a message to the given channel
Send an SMS message
POST https://{api-region}.nexmo.com/v1/messages
Server Variables
Api-region:
one of api, api-eu, api-us, api-ac
Authentication :
JWT or Basic
Body:
Required key value pairs in request body for SMS
+--------------+-----------------------+
| Key | value |
+--------------+-----------------------+
| channel | sms |
| message_type | text |
| from | the sender phone # |
| to | the recipient phone # |
| text | up to 1000 characters |
+--------------+-----------------------+
Responses:
202 Accepted
401 Authentication failure
402 Payment Required
404 Not Found
422 Unprocessable Entity
429 Too Many Requests
500 Internal error
METHODS
new
Creates a new Vonage object.
my $vonage = WWW::Vonage::API->new(
API_Key => 'YOUR_KEY',
API_Secret => 'YOUR_SECRET',
);
Available parameters:
- API_Key (Required)
-
Your Vonage API Key.
- API_Secret (Required)
-
Your Vonage API Secret.
- API_Domain
-
Defaults to 'nexmo.com'. There is one production api that uses a different domain as well as a number of 'beta' APIS. Simply use this parameter with the value of the domain you wish to access.
- API_Version
-
Defaults to 'v1'. This value will change by API and even within an API, see Vonage documentation for details. For example the 'Reports' API uses 'v2' and some calls in that API use 'v3'. Use 'none' for APIs that do not utilize a version string in the URL.
- API_Region
-
Defaults to 'api'. Use this parameter when the api documentation calls for something other than 'api'. The documented ones are 'api-eu', 'api-us', 'api-ac', 'rest' and 'video.api'.
Option Examples:
my $vonage = new WWW::Vonage::API(
API_Key => 'AC...',
API_Secret => '...',
);
would create the following url;
https://api.nexmo.com/v1/
my $vonage = new WWW::Vonage::API(
API_Key => 'AC...',
API_Secret => '...',
API_Version => 'v2'
);
would create the following url;
https://api.nexmo.com/v2
my $vonage = new WWW::Vonage::API(
API_Key => 'AC...',
API_Secret => '...',
API_Version => 'none',
API_Region => 'rest'
);
would create the following url;
https://rest.nexmo.com/
my $vonage = new WWW::Vonage::API(
API_Key => 'AC...',
API_Secret => '...',
API_Domain => 'vonage.com',
API_Version => 'v2',
API_Region => 'video.api'
);
would create the following url;
https://video.api.vonage.com/v2/
Vonage API calls
As Vonage is supposed to be a RESTful API, there is an expectation of a certain resource/entity path pattern for a given HTTP verb. For the most part Vonage follows the standard REST path pattern of:
'resource'
for the POST verb and some GET and PATCH verbs and
'resource/:entity_id'
for the DELETE, PATCH, PUT verbs and some GET verbs.
There are also a few APIs where there are parent-child calls as well in this pattern:
'resource/:entity_id/:child_entity'
for the POST verb and some GET and PATCH verbs and for the DELETE, PATCH, PUT verbs and some GET verbs the child_id is also included:
'resource/:entity_id/:child_entity/:child_entity_id'
There are a few that also include an extra resource in the path:
'resource_1/:entity_id/:child_entity/:child_entity_id/resource_2'
Consult the individual Vonage API documents for details on how each works.
All API calls are of the form:
VONAGE->METHOD(PATH, PAYLOAD, OPTIONS);
METHOD
Method is one of following HTTP verbs GET, POST, PATCH, DELETE and PUT.
GET
Requests a representation of a specific entity and in a Vonage API. It is used to retrieve data without modifying it. If the request has a 'PAYLOAD' it is encoded on the query string of the url.
POST
Sends data to a server to create a new entity and in some Vonage APIs it is used to initiate a specialized process. If the request has a 'PAYLOAD' it is encoded in JSON in the body of the request.
PATCH
Applies partial modifications to an existing entity rather than replacing it. If the request has a 'PAYLOAD' it is encoded in JSON in the body of the request.
DELETE
Removes the specified entity from the server. Normally there is no 'PAYLOAD' and the enitity_id is included in the request 'PATH'.
PUT
Replaces the current the target entity with the payload. In some Vonage APIs it will create the enitity if it doesn't exist. If the request has a 'PAYLOAD' it is encoded in JSON in the body of the request.
PATH
This is the Vonage API resource that is being invoked. Normally it is just a single resource, but that varies from API to API. This software expects that the full resource/entity path is included. For example a call with the PATCH verb of the 'project' resource requires this path pattern:
'resource_1/:entity_id/:child_entity/:child_id/resource_2'
and so the PATCH call to an entity would look like this:
$vonage->PATCH('project/999902/archive/19900/streams',$payload,...)
where 'project' is the resource, '999902' the entity id, 'archive' the child entity, '19900' the child_id and 'streams' the secondary resource.
PAYLOAD
A hash-ref of key-value pairs. For POST, PATCH, and PUT, verbs it is encoded as JSON in the request body. For GET, it is encoded on the query string.
OPTIONS
You can override API_Version, API_Domain, or API_Region on a per-call basis without creating a new instance. Note that these option values are sticky and will remain with a VONAGE instance until overwritten.
API Response
Each of GET, POST, PATCH, PUT and DELETE return a hashref with the call results, the most important of which is the content element. This is the untouched, raw response of the Vonage API server, suitable for you to do whatever you want with it. Normally it is a JSON object as in this example below;
my $payload = {
date_start => '2026-04-18',
date_end => '2026-04-23',
product => 'sms',
direction => 'outbound'
};
$response = $Vonage->GET('reports/records',$payload,API_Version=>'v2');
...
and B<$response> hash-ref will look like this;
{
content =>'{"message_uuid": "aaaaaaaa-bbbb-4ccc-8ddd-0123456789ab",
"workflow_id": "3TcNjguHxr2vcCZ9Ddsnq6tw8yQUpZ9rMHv9QXSxLan5ibMxqSzLdx9"}',
code =>'202',
message =>'Accepted',
}
The elements in the response are:
- content
-
Contains the JSON response from the server.
- code
-
Contains the HTTP status code. Successful responses will be in the '200' range. Make sure you check the Vonage API documentation to see what is the correct success code for the API you are invoking.
- message
-
A brief HTTP status message, corresponding to the status code. For 200 codes, the message will be "OK". For 202 codes the message will be "Accepted". For "400" codes, the message will be "Bad Request" and so forth. Again check the Vonage API documentation to see what the correct message and code is for the API you are invoking.
Example:
$response = $vonage->POST( 'Messages',$payload );
$response is a hashref that looks like this:
{
content =>'{"message_uuid": "aaaaaaaa-bbbb-4ccc-8ddd-0123456789ab",
"workflow_id": "3TcNjguHxr2vcCZ9Ddsnq6tw8yQUpZ9rMHv9QXSxLan5ibMxqSzLdx9"}',
code =>'202',
message =>'Accepted',
}
API Examples
Vonage is a rather large API so here are some basic examples that will cover most of the basics.
Reports API
In this example a report on 'SMS' outbound messages for a date range is required. The 'Reports API' is going to be invoked to fulfill this requirement. The resource that will be invoked is 'reports' and the entity is 'records'. According to the API documentation, these four parameters; start date, end date, product and direction, are required to be encoded on the URL Query String.
First the payload is created;
my $payload = {
date_start => '2026-04-18',
date_end => '2026-04-23',
product => 'sms',
direction => 'outbound'
};
Next a Vonage API instance is required;
my $Vonage = WWW::Vonage::API->new(API_Key => 'ABC12345...',
API_Secret => '1234567...');
then the API is invoked with this line:
my $response = $Vonage->GET('reports/records',$payload,API_Version=>'v2');
The response is a hashref that would look like this:
{ code =>'200',
message =>'OK',
content =>'{
"_links": {
"self": {
"href": "https://api.nexmo.com/v2/reports/sms/records?product=SMS&direction=outbound&date_start=2024-02-01T00:00:00Z&date_end=2024-02-02T00:00:00Z"
},
"next": {
"href": "https://api.nexmo.com/v2/reports/sms/records?product=SMS&direction=outbound&cursor=MTY0OTQ3ODAwMDAwMA"
}
},
...
Notes:
As the 'API_Version' parameter was not included in when creating the Vonage instance 'v1' is used as the default. According to the API document 'v2' is required so to invoke the correct version the 'API_Version' param is used.
Account API
In this example the current balance of the account is required. To get this value the 'Accounts API' must be used. So the 'account' resource is used in conjunction with the 'get-balance' entity.
In this case there is no payload, only a call to the API;
Starting with a new vonage instance:
my $Vonage = WWW::Vonage::API->new(API_Key => 'ABC12345...',
API_Secret => '1234567...',
API_Region => 'rest');
then the 'GET' call to the resource:
my $response = $Vonage->GET('account/get-balance',undef,API_Version=>'none');
The response is a hashref that would look like this:
{ code =>'200',
message =>'OK',
content =>'{"value": 10.28,"autoReload": false}'
}
Notes:
The API_Region param is used to set the first part of the URL to 'rest' when invoking the Vonage instance. The 'PAYLOAD' is set to 'undef' as there is no payload and finally the 'API_Version' param is use with a value of 'none' to drop the version number from the URL.
Account API
In this example a transaction notice needs to be sent to Vonage to update the balance of an account. The 'Accounts API' is again used to set this value using the 'POST' verb and the 'top-up' entity. The 'trx' param is required and it is encoded in the body of the post;
my $response = $Vonage->GET('account/top-up',{trx=>'8ef2...'});
The response in this case would be a hashref:
{ code =>'200',
message =>'success',
content =>''
}
Notes:
In the above example it was assumed the Vonage object is being reused from the previous example so it will maintain the values of API_Region and API_Version for its call.
More examples of using the params to set the path of an API call can be found in the .t files.
SEE ALSO
LWP::UserAgent, https://developer.vonage.com/
AUTHOR
John Scoles, <byterock@hotmail.com>
COPYRIGHT AND LICENSE
Copyright (C) 2026 by John Scoles
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
AUTHOR
John Scoles <byterock@hotmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by John Scoles.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
2 POD Errors
The following errors were encountered while parsing the POD:
- Around line 384:
You forgot a '=back' before '=head3'
- Around line 422:
=back without =over