How to Migrate from Pricing API v1 to Pricing API v2

Overview

This guide explains how to migrate from the Pricing API v1 to the Pricing API v2. The new version of the Pricing API includes changes to authentication, routes, and response structures. This guide will document the changes you need to make to your application so that you can update your integration.

Migrating to the Pricing API v2 is important to take advantage of the improved consistency, security, and flexibility offered by the new API.

Before you start

Before you begin your migration, ensure:

  • You have your existing Vonage API Key and API Secret.
  • You have reviewed this documentation to understand the new features and capabilities.
  • You have a testing or development environment to test changes before deploying to production.

Note the URL Change

The Pricing API v2 uses a new base URL for the API compared to v1.

  1. In your application, change the base URL and route from https://rest.nexmo.com/account/get-pricing/outbound/ to https://api.nexmo.com/v2/account/pricing/

    // Example using the old route
    const apiKey = 'vonage_api_key'; // Replace with your API Key
    const apiSecret = 'vonage_api_secret'; // Replace with your API Secret
    const product = 'sms'; // Example product
    const country = 'CA'; // Example country code
    
    const url = `https://rest.nexmo.com/account/get-pricing/outbound/${product}?api_key=${apiKey}&api_secret=${apiSecret}&country=${country}`;
    
    // Example using the new route
    const apiKey = 'vonage_api_key'; // Replace with your API Key
    const apiSecret = 'vonage_api_secret'; // Replace with your API Secret
    const product = 'sms-outbound'; // Example product
    const country = 'CA'; // Example country code
    
    const url = `https://api.nexmo.com/v2/account/pricing/${product}`
    

Select the Appropriate Product

The Pricing API v2 only supports sms-outbound and voice-outbound, compared to the Pricing API v1 which supported sms, sms-transit, and voice. You will need to make sure to call the appropriate product name as this will change. In most cases sms-transit and sms can be changed to sms-outbound, and voice can be changed to voice-outbound.

Migrate to Basic Header Authentication

The Pricing API v1 used query parameter authentication to validate your request, and the Pricing API v2 now utilizes Basic Authentication using the Authorization header.

  1. Find the API request in your current application. If you are using Node.js, your requests may look like the following:

    const fetch = require('node-fetch');
    
    const apiKey = 'vonage_api_key'; // Replace with your API Key
    const apiSecret = 'vonage_api_secret'; // Replace with your API Secret
    const product = 'sms'; // Example product
    const country = 'CA'; // Example country code
    
    const url = `https://rest.nexmo.com/account/get-pricing/outbound/${product}?api_key=${apiKey}&api_secret=${apiSecret}&country=${country}`;
    
    fetch(url)
        .then(response => {
            if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            console.log('Pricing Data:', data);
        })
        .catch(error => {
            console.error('Error fetching pricing data:', error);
        });
    
    const axios = require('axios');
    
    const apiKey = 'vonage_api_key'; // Replace with your API Key
    const apiSecret = 'vonage_api_secret'; // Replace with your API Secret
    const product = 'sms-outbound'; // Example product
    const country = 'CA'; // Example country code
    
    const url = `https://rest.nexmo.com/account/get-pricing/outbound/sms`;
    
    axios
        .get(url, {
            params: {
            api_key: apiKey,
            api_secret: apiSecret,
            country: country,
            },
        })
        .then(response => {
            console.log('Pricing Data:', response.data);
        })
        .catch(error => {
            console.error('Error fetching pricing data:', error.response ? error.response.data : error.message);
        });
    
  2. Remove the api_key and api_secret parameters, and replace them with an Authentication header that uses Basic authentication.

    // Example using Node Fetch
    const fetch = require('node-fetch');
    
    const apiKey = 'vonage_api_key'; // Replace with your API Key
    const apiSecret = 'vonage_api_secret'; // Replace with your API Secret
    const product = 'sms-outbound'; // Example product
    const country = 'CA'; // Example country code
    
    const url = `https://api.nexmo.com/v2/account/pricing/${product}?country=${country}`;
    
    fetch(url, {
        method: 'GET',
        headers: {
            Authorization: `Basic ${Buffer.from(`${apiKey}:${apiSecret}`).toString('base64')}`,
        },
    })
        .then(response => {
            if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            console.log('Pricing Data:', data);
        })
        .catch(error => {
            console.error('Error fetching pricing data:', error);
        });
    
    // Example using Axios
    const axios = require('axios');
    
    const apiKey = 'vonage_api_key'; // Replace with your API Key
    const apiSecret = 'vonage_api_secret'; // Replace with your API Secret
    const product = 'sms-outbound'; // Example product
    const country = 'CA'; // Example country code
    
    const url = `https://api.nexmo.com/v2/account/pricing/${product}`;
    
    axios
        .get(url, {
            auth: {
                username: username,
                password: password,
            },
            params: {
                country: country,
            },
        })
        .then(response => {
            console.log('Pricing Data:', response.data);
        })
        .catch(error => {
            console.error('Error fetching pricing data:', error.response ? error.response.data : error.message);
        });
    

Change to Process the New Response Structure

The Pricing API v2 now utilizes a JSON-HAL response structure to make it more consistent with other Vonage APIs. This is a different API response structure than the more flat response structure from the Pricing API v1, but provides some additional benefits like better paging of results.

  1. Note the change in data location in the response. The pricing and network information is now found in the _embedded.countries array instead of the networks array.

    // Pricing API v1 Response
    {
        "countryCode": "CA",
        "countryName": "Canada",
        "countryDisplayName": "Canada",
        "currency": "EUR",
        "defaultPrice": "0.00620000",
        "dialingPrefix": "1",
        "networks": [
            {
                "type": "mobile",
                "price": "0.00590000",
                "currency": "EUR",
                "mcc": "302",
                "mnc": "530",
                "networkCode": "302530",
                "networkName": "Keewaytinook Okimakanak"
            }
        ]
    }
    
    // Pricing API v2 Response
    {
        "page_size": "100",
        "page": "1",
        "total_items": "243",
        "total_pages": "3",
        "_embedded": {
            "countries": [
                {
                    "country_name": "Canada",
                    "dialing_prefix": "1",
                    "dest_network_type": "ALL",
                    "group_internal_start": "1s",
                    "rate_increment": "60",
                    "currency": "USD",
                    "price": "0.1"
                }
            ]
        },
        "_links": {
            "self": {
                "href": "https://api.nexmo.com/account/pricing/sms-outbound?page=1&page_size=100"
            },
            "first": {
                "href": "https://api.nexmo.com/account/pricing/sms-outbound?page=1&page_size=100"
            },
            "last": {
                "href": "https://api.nexmo.com/account/pricing/sms-outbound?page=3&page_size=100"
            },
            "next": {
                "href": "https://api.nexmo.com/account/pricing/sms-outbound?page=2&page_size=100"
            },
            "prev": {
                "href": "https://api.nexmo.com/account/pricing/sms-outbound?page=1&page_size=100"
            }
        }
    }
    
  2. Note the changes to key names. Key names now use snake_case instead of camelCase. This conforms to Vonage's API standards and keeps it consistent with our other API responses. Some locations of the keys have changed as well.

  • countryCode is now located in the URL as the country query parameter.
  • countryName is now located at _embedded.countries[X].country_name.
  • countryDisplayName is now located at _embedded.countries[X].country_name.
  • currency is now located at _embedded.countries[X].currency.
  • defaultPrice is now located at _embedded.countries[X].price.
  • dialingPrefix is now located at _embedded.countries[X].dialing_prefix.
  • network[X].type is no longer returned.
  • network[X].price is now located at _embedded.countries[X].price.
  • network[X].currency is now located at _embedded.countries[X].currency.
  • network[X].mcc is no longer returned.
  • network[X].mnc is no longer returned.
  • network[X].networkCode is no longer returned.
  • network[X].networkName is no longer returned.
  1. The response now more accurately reflects paging. You can compare the page key with the total_pages key to see if you are at the end of results, or check for the existence of the _links.next key. If you need to move to the next page, you can use the _links.next.href value to automatically determine and navigate to the next page.

See also