Skip to main content

Version 3

Overview

What is it?

The Simwood Customer API ("Application Programming Interface") is a way for your own back-office systems and web sites to seamlessly integrate with Simwood and manage your wholesale telephony account and services.

What can I do with it?

The API is the preferred way to configure your Simwood services. Everything in the portal can also be configured via the API (and in some cases the API offers some additional functionality) Our portal is based on the API, and everything you can do in the portal you can do through the API in your own code. We’ve deliberately made it this way. The only exception to this is the authentication elements of the portal, as using your API key to log in on the web would be cumbersome.

Databases

As before, many queries are made against MySQL although we have dedicated servers for the API’s use. These are built for queries and are slaves of masters. We can build additional query servers sideways as required. Writes are, of course, made against the masters. Increasingly, API requests are served directly from our underlying REDIS ram-based data stores where possible.

Middle-ware

This API introduces multiple layers in between the above for performance and scale:

Beanstalkd Queues

We use Beanstalkd a lot for internal messaging. In this API where a request is non-trivial and involves other processes, we’ll simply queue a job.

REDIS

REDIS replaced memcached as our caching data store, and is used for much more as it supports a number of advanced data structures facilitating vastly improved monitoring and real-time information. See http://blog.simwood.com/2013/06/real-time-big-data/ for more information.

App Servers

We have numerous daemons running monitoring specific queues (pipes in beanstalkd language). One of the beautiful features of beanstalkd is that it is blocking, i.e. 10 daemons can watch the same pipe and code will block waiting for a response. One, and one only, will be given the job when there is one. This avoids polling – meaning this is extremely efficient and very scalable as we can just spin up as many daemons as required. Further, release of a job to a daemon is sub-millisecond giving the queueing the performance of direct requests. Most complicated jobs involve multiple daemons working through a sequence of queues.

Basic Operations

The Simwood API can be found at the following URI; https://api.simwood.com/v3/

Please note that TLS v1.1 or Higher is Mandatory for all requests.

Basic GET Requests

A number of end-points in the API can be accessed with a simple GET request and will therefore work in a browser. Some do not require authentication and are a good place to start and to test connectivity to the API.

Two simple examples are:

https://api.simwood.com/v3/tools/myip - will return your IP address as seen by the API https://api.simwood.com/v3/tools/time - will return a timestamp from the API

JSON Output Format

You’ll see that in both above cases the output is JSON, e.g:

{"timestamp":1388748052,"rfc":"Fri, 03 Jan 2014 11:20:52 +0000"}

JSON ("JavaScript Object Notation") is used as it’s a lightweight format designed for exchange of data structures which has an additional advantage of being relatively human readable. All modern languages such as PHP, ASP, .net, Node, Perl etc can handle JSON structures and convert to/from their native objects or arrays easily making it the ideal choice for REST APIs.

"Pretty" JSON

JSON is designed to be machine-readable and as such is sent with minimal whitespace by default however when developing it is often useful to see the output in a more human-friendly format, you can achieve this simply by appending "?pretty=true" to any endpoint e.g https://api.simwood.com/v3/tools/time?pretty=true would look like this;

{
"timestamp": 1388748052,
"rfc": "Fri 03 Jan 2014 11:20:52 +0000"
}

Authenticating Requests

Most commands are linked to an account and therefore require authentication. We use standard Basic Authentication, i.e. your client makes a request, we respond with a 401 response code, your client replies with the API username and password included. Your API username and password were provided at the time of creating your Simwood account, if you do not have these please contact our support team and we’ll be happy to provide you with them.

Note that, at present;

  • Your API username and password is not the same as your portal login details
  • Your API password is designed to be used programatically, and is typically not memorable
  • Your API details allow full access to your account, and must be protected accordingly.
  • You cannot, currently, change your API username or password - although our support team are happy to do so if required (e.g. if your details are lost or you have reason to believe they are compromised)

If you pull up an example URL in your browser it’ll do this for you. For your code, different development languages will tackle this in different ways but most will ‘just deal with it’ automatically for you. cURL for example, will just take the username and password as parameters, e.g.:

curl --user name:password https://api.simwood.com/v3/…

PHP’s cURL implementation is very similar in that you’d set CURLOPT_USERPWD with curl_setopt.

An example authenticated GET request is:

https://api.simwood.com/v3/accounts/{ACCOUNT}/prepay/balance

This example URL will not work directly in a web browser as the {ACCOUNT} placeholder in the above will need to be replaced with account ID (typically a six digit number)

Which would return the following

[{"balance":"12.32","currency":"GBP"}]

Adding ?pretty=true to the end of the URL would give you the same information in the following format;

[
{
"balance": "12.32",
"currency":"GBP"
}
]

Both are treated equally by a JSON parser, and are syntactically valid, however the ‘pretty-printed’ version may be useful for debugging. Simwood

PUT and DELETE requests

In the spirit of being REST-ful, many URLs can be acted upon with different methods. The URL does not change, only the HTTP method used against it. One example of this is number configuration, for example;

https://api.simwood.com/v3/numbers/{ACCOUNT}/allocated/{NUMBER}

Again, this will not work as {ACCOUNT} and {NUMBER} need replacing with real data. {NUMBER} is the e164 representation of the number, e.g. 442031234567.

GET is the default method, accessing the above end-point with a GET will return the current configuration of that number. PUT will create the end-point, i.e. allocate the number to your account if it does not exist already. DELETE will remove the end-point, i.e. de-configure and remove the number from your account. PUT is context sensitive and specific uses will be described in greater detail within different commands. Briefly though, whereas:

https://api.simwood.com/v3/numbers/{ACCOUNT}/allocated/{NUMBER}

will create a number end-point, i.e. allocate the number but

https://api.simwood.com/v3/numbers/{ACCOUNT}/allocated/{NUMBER}/config

will configure a number, i.e. write the sent config to it. DELETE works more uniformly but only at the level it operates, e.g.

https://api.simwood.com/v3/numbers/{ACCOUNT}/allocated/{NUMBER}

will de-configure and remove a number but

https://api.simwood.com/v3/numbers/{ACCOUNT}/allocated/{NUMBER}/config

will just remove the configuration, leaving the number on your account

Setting the method is language specific and PUT and DELETE cannot be easily replicated in a browser. Almost all environments/browsers will default to GET so the chances are if it doesn’t work as you expect you are using the GET method. For development languages which do not permit all HTTP methods to be used you can pass a hidden parameter named _method in an HTTP POST or GET and set the method to use in there. This will override the actual HTTP method used. For example, in an HTTP form you may use: <input type="hidden" name="_method" id="_method" value="put" />

  • All modern languages allow HTTP methods to be used correctly, and we would strongly encourage this in preference to setting a _method parameter.

POST requests / Reports

POST is very similar to PUT but is used where one is not updating a specific resource, i.e. requesting reports, or when creating a new resource For example, to request a summary of calls and charges for the current day the end-point would be:

https://api.simwood.com/v3/accounts/{ACCOUNT}/reports/voice/summary/day/in

You would use POST for this request as whilst you are sending a request to the server and the end-point is fixed, what that end-point represents and what you get back are variable. POST is used for all report type requests.

The output from such a POST request (which requests a report) will typically be small, i.e.:

{"mode":"vsind","date":"2012-01-28","type":"voice_summary","account":"ACCOUNT","format"
:"json","hash":"4e591630fedf4aa149db9874fb33fe23","link":"\/v3\/files\/ACCOUNT\/
4e591630fedf4aa149db9874fb33fe23"}

You will note that this is not in fact a summary of today’s charges. It is a hash that uniquely identifies that report and a link to it. As the return suggests, you can retrieve the actual results with a GET request to

https://api.simwood.com/v3/files/{ACCOUNT}/4e591630fedf4aa149db9874fb33fe23.

But don’t worry...

Whilst is is important to understand the effect a given request method will have, we are somewhat relaxed in our interpretation of them where possible. DELETE is always DELETE with no alternative but we will accept a POST instead of a PUT and a GET instead of a POST where possible. You should not assume we will, and should adhere to the RESTful way, but this flexibility is there if you wish to test behaviour in a browser for example.

Report De-duplication

As described above, when you request a report the return will just contain a link to the results. That link will be unique to that specific report, i.e. in the above example the hash for today’s summary will be the same with every request, but only every request today. Tomorrow will generate a different hash. If you make multiple requests for the same report before you retrieve it, duplicates will simply be ignored and the report will only be run once.

However, once a report has been run, the results await your collection within the next 5 minutes. Further requests with the same hash will continue to be ignored as long as that report exists. Once the report is retrieved it will be deleted. Only after a report has been deleted (either by retrieval or expiry), will an identical report request result in a new report.

NB reports expire after 5 minutes, any attempt to access the report after 5 minutes will result in a 404 error, you should therefore build your application to poll the report URL multiple times as soon as possible after submitting your request or use the callback URL detailed below.

Hashes are intended to be generated sensibly. For example, a given report for today will always give the same hash. A different report for today or the same report for tomorrow will give different hashes. Reports on different numbers will generate different hashes. Further, de-duplication will only apply where previous results have not been retrieved.

The intention here is to protect the system from the coder who wishes to request a year’s CDRs every second. He can, but all requests other than the first will be ignored until he retrieves the results. This rather extreme example is actually real and was a consequence of the way the v2 API paginated results and required clients to step through them. More than a few customer implementations reached the end of the results and went into a race condition.

Report Retrieval

As shown above, the return from a report request will give a hash and an encoded URL. The hash can be used to access the results directly, even from another system, using a GET request to, for example:

https://api.simwood.com/v3/files/{ACCOUNT}/4e591630fedf4aa149db9874fb33fe23

This URL can be polled at a sensible interval as it will simply return a 204 No Content until the report exists. Once the report does exist, it can be downloaded only once and then will be automatically deleted. To negate the need for polling, clients may instead wish to specify a ‘callback’ URL with their request. This should be POSTed as a variable called ‘callback’. The response to the request will be identical as without it but on successful generation of the report we will make a POST to the URL provided. This will contain a single HTTP POST variable call ‘payload’ which will contain the report hash in JSON format, e.g.:

{"app":"reports","id":"76e7a8102f93c636785ea8432c72e07a","data":null}

The client should then GET the report as usual within a maximum of 5 minutes, after which it may expire.

Dates in Reports

Most reports can be run for a range or at a specific date. Where omitted they will generally default to today. Dates are always expressed in MySQL format (YYYY-MM-DD hh:mm:ss), e.g. 2012-01-01 14:30:00

File (Report Output) Handling

Unlike many APIs the Simwood API is asynchronous when requesting some complex reports to improve performance (this is discussed in more detail above) and some POST requests will result in a small response containing a hash and ‘link’ to a file e.g.

{
"mode":"vsind",
"date":"2012-01-28",
"type":"voice_summary",
"account":"{ACCOUNT}",
"format":"json",
"hash":"4e591630fedf4aa149db9874fb33fe23",
"link":"/v3/files/{ACCOUNT}/4e591630fedf4aa149db9874fb33fe23"
}

The functions below are used to retrieve these;

/v3/files/{ACCOUNT}

GETLists uncollected files on the account
{
"ff98d8d8fdf9dfd178e72b6e6ba207ff" {
"name":"ff98d8d8fdf9dfd178e72b6e6ba207ff",
"content_type":"application/json",
"length":410,
"uri":"/v3/files/ACCOUNT/ff98d8d8fdf9dfd178e72b6e6ba207ff"
}
}

/v3/files/{ACCOUNT}/{HASH}

GETRetrieve specific file on account, where HASH is the hash returned when the report was requested. File will be deleted after retrieval.

API Endpoints

If the above has all made sense, you should need little more than a list of the available end-points and the HTTP methods they support to get going. This follows and you’ll quickly observe they are hierarchical and hopefully consistent. The method shown indicates behaviour as described earlier.

Each endpoint is documented below in the following format;

/v3/URL

GETExplains what happens when the GET method is used
POSTExplains what happens when the POST method is used. Will also explain what parameter is used for
parameter - An example GET / POST or PUT parameter
anotherparam - Another parameter to be sent by POST

Please Note - Where example responses are shown in this documentation they may be reformatted to be more easily human-readable, the actual response will have escaped slashes (e.g. / replaced with \/) and not include any excess white space.

The following conventions are used in describing the URL or other parameters
{ACCOUNT}Where a word is capitalised and enclosed by curly braces { } it must be replaced with the appropriate information e.g. {ACCOUNT} or {IP}
[ on | off ]Where two or more words are separated by the pipe character | and enclosed within square brackets [ ] these are ‘either or’ options. e.g. a url with the form /latest/[1|5|10] allows you to specify any of the following 3 URLs;
/latest/1
/latest/5
/latest/10
Arbitrary values (e.g. /latest/15) are not supported
URLsThe URLs are shown without the leading https://api.simwood.com/ which must be inserted before the /v3/ when making any API call.
paramnameParameters are shown in italics, these are passed by GET, POST or PUT in the request and do not form part of the URI (except in the case of the GET request, when they are part of the query string after the ? mark)
paramname[]Parameters with square brackets at the end are different and can be thought of as Array Parameters. These can be passed multiple times but even if only one item is being included you must include the [] on the end. For compatibility with some languages (e.g. PHP with Curl) an integer value can be between the square brackets e.g the following two examples are equivalent;
?param[]=apple&param[]=orange&param[]=pear
?param[0]=apple&param[1]=orange&param[2]=pear

Tools

The following tools are made available without authentication to help integrate with the Simwood API.

IP Address

Your IP address, as seen by the Simwood API service

curl https://api.simwood.com/v3/tools/myip
Request Typeresult
GETReturn your external IP address, as seen by the Simwood API

Time

The current server timestamp

curl https://api.simwood.com/v3/tools/time
Request Typeresult
GETReturns the current timestamp

Explain

This tool is provided to help debug requests to the Simwood API. It accepts any request method (GET, PUT, POST, DELETE etc) and returns a human-readable report of the information submitted.


curl "https://api.simwood.com/v3/tools/explain?test=1&pretty=true"

or

curl -X POST "https://api.simwood.com/v3/tools/explain?test=1&pretty=true"
Request TypeResult ANY Returns human-readable report of the request receive
Simwood API - Explain Tool
========================================================
Query ID: swAPI6410ece80eaff
Timestamp: 2023-03-14 21:53:44
HTTP Request Method: GET
API Request Method: GET
== Query String ========================================
Your query string contained 2 elements;
test => 1
pretty => true
== HTTP Post Vars =====================================
No HTTP request body request elements
== JSON Request ========================================
No JSON Request body
== Raw Request ========================================

=======================================================
Simwood API v3 http://mirror.simwood.com/pdfs/APIv3.pdf

NB As this is intended to be a human-readable report for debugging purposes the format may change at any time, and without notice, and should not be relied upon.

Account Management

Account Type

Your account will be one of the following four types; developer, startup, virtual_interconnect, or managed_interconnect, each have different commercials but are functionally identical. All new accounts start off as ‘Developer’, we encourage you to move to ‘Start-Up’ for production use, and to consider ‘Virtual Interconnect’ or ‘Managed Interconnect’ as your requirements evolve.

The differences between these account types can be found in the Simwood Account Pricing document.

/v3/accounts/{ACCOUNT}/type
curl  --user $CARRIER_API_USERNAME:$CARRIER_API_PASSWORD https://api.simwood.com/v3/accounts/$ACCOUNT/type
please replace all variables above for the curl command to work. check introduction page to see how you can set envronmental variabls in your lab.
Request Typeresult
GETGet your current account type, and limitations Account type will be one of the following; developer, startup, virtual_interconnect, managed_interconnect
PUTUpgrade or downgrade your account
This option is only available to customers of account_type developer or startup
account_type updgrade to developer(if startup), or upgrade to startup(if developer)

Charges Apply

$.. There is a minimum commitment associated with the Start-Up package, along with other commercial differences. Please see the Simwood Product Brochure for more information

PLEASE NOTE

You can migrate between developer and startup at any time. By changing your package type to Start-Up please ensure you are aware of the commercial obligations of this package, including the minimum pre- payment amount (which differs from the developer package) and the minimum total spend per month, which replaces the service charge of the Developer pack.

It is not possible to switch to our Virtual Interconnect or Managed Interconnect options online either via the API or Portal. Please contact us if you are interested in these packages.

If you are unsure, please contact our Operations Desk via eMail to team@simwood.com, or call us on 0330 122 3000 to discuss your requirements further.

Credit Account Management

The current status of all invoices on your account is available through the API.

#List of unpaid invoices on account (since June 2010)
curl --user $CARRIER_API_USERNAME:$CARRIER_API_PASSWORD https://api.simwood.com/v3/accounts/$ACCOUNT/credit/invoices/unpaid

#List of paid invoices on account (since June 2010)
curl --user $CARRIER_API_USERNAME:$CARRIER_API_PASSWORD https://api.simwood.com/v3/accounts/$ACCOUNT/credit/invoices/paid

#List of invoices on account (since June 2010)
curl --user $CARRIER_API_USERNAME:$CARRIER_API_PASSWORD https://api.simwood.com/v3/accounts/$ACCOUNT/credit/invoices/all

PDF Copy Invoices

/v3/accounts/{ACCOUNT}/credit/invoices/{INVOICE_NUMBER}[.pdf]

Prepay Account Management

/v3/accounts/{ACCOUNT}/prepay/summary

curl  -X POST --user $CARRIER_API_USERNAME:$CARRIER_API_PASSWORD https://api.simwood.com/v3/accounts/$ACCOUNT/prepay/summary
POSTRequests a report of Summary of account movements. If the optional from_date and to_date parameters are not specified will default to today.
from_date Start date of report (in form YYYY-MM-DD)
to_date End date of report (in form YYYY-MM-DD)

Other examples

#GET List all account pre-payments
/v3/accounts/{ACCOUNT}/prepay/prepayments/all

#GET List last (1) or last ten (10) pre-payments to account
/v3/accounts/{ACCOUNT}/prepay/prepayments/latest/[1|10]

#GET Transfers between this prepay account and others.
/v3/accounts/{ACCOUNT}/prepay/transfers/all

#List last (1) or last ten (10) transfers on the prepay account
/v3/accounts/{ACCOUNT}/prepay/transfers/latest/[1|10]

Prepay Account Balance

The API provides tools for checking and protecting your pre-paid balance(s)

#Return balance of account
/v3/accounts/{ACCOUNT}/prepay/balance

Example result

[
{
"balance": "168.06100",
"currency": "GBP"
}
]

Low Balance Alerts

You can set an amount at which you will receive a notification (configured via the notifications, detailed below) when your balance drops below the specified amount. A maximum of one notification will be sent per day.

/v3/accounts/{ACCOUNT}/prepay/balance/alert

GET

Returns the current level of alert.

[
{
"account": ACCOUNT,
"alert_balance": 90
}
]
PUT

Sets the alert balance to the specified alert_balance

alert_balance The balance at which an alert should be generated

Balance Locking

We provide the ability to ‘lock’ a portion of your balance to make it unavailable to spend. i.e. you can specify the balance at which we’ll treat your account as ‘out of credit’ and therefore kill calls in progress.

This is normally zero but the balance locking facility enables customers to keep large credit balances without risking the entire amount in the event that they, or a customer, suffer a compromise.

You can set alerts based on the available balance (i.e. balance-locked balance) using the balance alert above.

/v3/accounts/{ACCOUNT}/prepay/balance/locked

MethodDescription
GETReturns the ‘locked’ balance, this represents a portion of your pre-paid balance that cannot be consumed - e.g. to protect against unexpected spend
[{"account":ACCOUNT,"balance":10.4688,"locked":5,"available":5.4688}]
PUTSets the protected amount to the specified balance. This amount remains in your account but cannot be spent.
balance The amount to be protected.
DELETERemove the locked balance, allowing the full amount of your pre-paid balance to be used for calls.

NB The above ‘locked balance’ function is provided on a ‘best-efforts’ basis and is not intended as a substitute for securing your own VoIP platform. You remain responsible for all calls made on your account.

Termination Rate Functions

Available Tariffs

Some account types have more than one available tariff or rate deck, these can be viewed as follows where this is applicable to your account;

/v3/accounts/{ACCOUNT}/rates/tariffs

MethodDescription
GETRequest tariffs available on your account, these are shown together with the prefix required for dynamic rate deck selection (no prefix is required for calls using the default rate deck)

Example result

{
"success": true,
"data": [
{
"description": "Legacy GBP Platinum",
"servicelevel": 1,
"quality": "Platinum",
"prefix": 999001,
"url": "\/v3\/accounts\/929999\/rates\/csv\/Simwood_Platinum.csv"
}, {
"description": "Legacy GBP Gold",
"servicelevel": 2,
"quality": "Gold",
"prefix": 999002,
"default": true,
"url": "\/v3\/accounts\/929999\/rates\/csv\/Simwood_Gold.csv"
}
] }

Ratecard Downloads (CSV Format)

Our latest termination rates are also always available in CSV and Excel (XLSX) format from the portal https://portal.simwood.com/ or in CSV format via the API;

/v3/accounts/{ACCOUNT}/rates/csv/[default|silver|platinum|gold|name]

#Get Request the latest ratecard in CSV Format
curl --user $CARRIER_API_USERNAME:$CARRIER_API_PASSWORD https://api.simwood.com/v3/accounts/$ACCOUNT/rates/csv/default

NB: The options silver, platinum and gold are only for ‘legacy’ or ‘startup’ account types with multiple rate decks. Virtual Interconnect and Managed Interconnect customers should use default or the file name provided from the above query


Destination Lookup

/v3/accounts/{ACCOUNT}/rate/{NUMBER}

MethodDescription
GETReturns the cost of calling the specified number in your account currency. Each rate array is keyed by the relevant deck (1 - platinum, 2 - gold, 3 - silver) and shows (p)eak, (o)ffpeak, (w)eekend rates and the (c)onnection charge.
#Get Note number is in 164 format. ie UK is 44XXXXXXXXXX
curl -X POST --user $CARRIER_API_USERNAME:$CARRIER_API_PASSWORD https://api.simwood.com/v3/accounts/$ACCOUNT/rate/$NUMBER

General Accounting Reports / CDRs

/v3/accounts/{ACCOUNT}/reports/voice/summary/day/[in|out]

MethodDescription
POSTRequest a summary of [incoming] or [outgoing] voice charges
date Optionally specify date in YYYY-MM-DD format to request report as at date, otherwise defaults to current.

/v3/accounts/{ACCOUNT}/reports/voice/cdr/day

MethodDescription
POSTRequest daily CDR report
date Optionally specify date in YYYY-MM-DD format to request report as at date, otherwise defaults to current.

/v3/accounts/{ACCOUNT}/reports/voice/cdr/latest/[10|100|1000|10000]

MethodDescription
POSTRequest report of last [ 10 | 100 | 1,000 | 10,000 ] Voice CDRs

/v3/accounts/{ACCOUNT}/reports/sms/cdr/day

MethodDescription
POSTRequest daily SMS CDR report
date Optionally specify date in YYYY-MM-DD format to request report as at date, otherwise defaults to current.

/v3/accounts/{ACCOUNT}/reports/sms/cdr/latest/[10|100|1000|10000]

MethodDescription
POSTRequest report of last [ 10 | 100 | 1,000 | 10,000 ] SMS CDRs

Summary Reports (Instant)

The new Summary Reports are, unlike the CDRs above, not asynchronous, the response is inline.

NB These are intended to be indicative only and are not suitable for billing purposes.

/v3/accounts/{ACCOUNT}/summary/([in|out])/{KEY}

MethodDescription
GET / POSTRequest an inbound or outbound summary report by {KEY} (see below). If ‘in’ or ‘out’ is omitted from the URI bi-directional traffic will be shown.
The parameters below can be provided in the query string (with the exception of the ‘filter’ parameter) or, preferred, as a JSON object in the request
date_startOptionally specify date/time in YYYY-MM-DD HH:mm:ss format to request report from date_start, otherwise defaults to start of current day. NB Dates must be specified in GMT
limitOptionally specify limit of results to return, default 9999
sortKey to sort by
filterArray of "search_key" => "value" e.g. {"trunk": "930000-TEST"} would generate a report only for the trunk named "930000- TEST"

Summary Report Keys

The following keys are available for summary reports;

KeyDescription
destidSummary by Destination ID
isoSummary by ISO Country Code (of destination)
codecSummary by Codec
tagSummary by Tag (as set with "X-simwood-tag" header)
trunkSummary by Trunk

Example Summary Report

The report below was generated based on a key of ‘trunk’ with a sort of ‘calls’;

[
{
"trunk": "930000-ACME",
"calls": 378,
"acd": 1.6,
"minutes": 603.32,
"charges": 8.32
},
{

"trunk": "930000-WIDGETINC",
"calls": 2856,
"acd": 1.56,
"minutes": 4458.47,
"charges": 23.01

}
]

Event Notifications

Some notifications can now (as of v3.15) be received via Webhooks, for more information see https://cdn.simwood.com/docs/simwood_webhooks_beta.pdf

/v3/accounts/{ACCOUNT}/notifications

MethodDescription
GETList available notifications on your account
["blocked_calls","prepay_debit"]

/v3/accounts/{ACCOUNT}/notifications/available

MethodDescription
GETList available notification TYPEs

/v3/accounts/{ACCOUNT}/notifications/{TYPE}

MethodDescription
GETList configured recipients for notifications of {TYPE}
DELETEDelete all configured notifications of {TYPE}

/v3/accounts/{ACCOUNT}/notifications/{TYPE}/{METHOD}

MethodDescription
GETShows all configured recipients of notifications of {TYPE} using {METHOD}
METHOD is one of email or sms*
POSTAdd a new notification recipient to receive notifications of {TYPE} using {METHOD}. Returns a hash corresponding to this recipient
destination eMail address or Mobile Number (in E164 format) of the recipient.

/v3/accounts/{ACCOUNT}/notifications/{TYPE}/{METHOD}/{HASH}

MethodDescription
GETShows the ifnormation on this recipient
DELETEDeletes this recipient

The {HASH} referred to above can be generated locally and is simply an md5()’d version of the notification address. This is used simply to avoid potential url encoding issues.

*SMS notification requires credit balance, sent messages will be deducted from your usual credit.

/v3/accounts/{ACCOUNT}/notifications/history

MethodDescription
GETRetrieve a history of recent (last 60 days) notifications on your account All parameters below are optional, by default will return all notifications for the last 60 days.
Returns a JSON Array of Objects, each Object contains a "data" attribute which contains an Object containing all variables in the original notification.
Please note if the original message contained a password it will be redacted and replaced with ###### as these are not stored.
classClass of notification ( e.g. trunk or billing )
date_startStart date (no more than 60 days ago)
date_endEnd date (YYYY-MM-DD HH:ii:ss)

Voice Termination

Account Limits (and Dynamic Channel Limits)

/v3/voice/{ACCOUNT}/limits

GET Shows limits in effect on an account including any Dynamic Channel Limits



{
"channel_allocation": 30,
"channel_allocation_global_numbers": 10,
"channel_allocation_adjustable": false,
"limit_concurrent_in": 10,
"limit_concurrent_out": 20,
"limit_concurrent_out_per_number": 10,
"limit_concurrent_out_international": 3,
"limit_concurrent_out_hotspot": 2,
"limit_rate_out": "10/1s",
"limit_rate_out_international": null,
"limit_rate_out_hotspot": "2/12h",
"dynamic": {
"balance": "15.52680",
"limit_concurrent_out": 3,
"limit_rate_out": "30/10s"
} }

Dynamnic Channel Limits

Applies only to accounts without a dedicated channel allocation Any dynamic channel limits shown in the "dynamic" block take precedence over the usual account limits. e.g. in the above example due to the low balance there is a concurrent channel limit of 3 channels and a rate limit of 30 calls per 10 seconds.

Channel Allocation (Inbound/Outbound)

Applies only to accounts with a dedicated channel allocation

For customers with a dedicated self-managed channel allocation, channel_allocation_adjustable is true. You can divide this allocation between inbound and outbound as described below.

Channel Allocation (Global Numbers)

Applies only to accounts with global numbers

For customers with global numbering (i.e. non UK or USA), channel_allocation_global_numbers reflects the inbound channel allocation across your Global Numbers

Other Limits

These limits are set per-account by Simwood and are based on your traffic.

We impose these limits to protect and manage our network utilisation.

If you require more channels or a higher rate of calls per second please contact team@simwood.com

Adjusting your Channel Allocation

Customers with a dedicated channel allocation can manage this allocation, splitting channels between inbound and outbound as required. /v3/voice/{ACCOUNT}/limits

 {
"limit_concurrent_in": 10,
"limit_concurrent_out": 20
}
PUTUpdate channel limits
JSON request
limit_concurrent_ininbound channel Limit
limit_concurrent_outoutbound channel Limit
NB the above must, together, total the value of channel_allocation
JSON response
{
"success": true
"data": {
"limit_concurrent_in": 10,
"limit_concurrent_out": 20
} }

Channel Statistics

/v3/voice/{ACCOUNT}/channels/current

# GET Current channel utilisation
NB: this is returned as an array (with one member) for compatibility with the /channels/history function detailed below

[
{
"datetime": "2014-02-30 12:34:35",
"channels": 22,
"channels_in": 10,
"channels_out": 12
}
]

/v3/voice/{ACCOUNT}/channels/history

GET
Recent (around 24h) channel utilisation samples The channels count shows the peak number of channels in use between the previous datetime timestamp and the current one.
interval
Optional interval for samples in the following form;
1m - One Minute
5m - Five Minutes(Default)
1h - Hourly

[
{
"datetime": "2023-03-18 17:40:00",
"channels": 11,
"channels_out": 10,
"channels_in": 1
},
{
"datetime": "2023-03-18 17:30:00",
"channels": 11,
"channels_out": 10,
"channels_in": 1
},
{
"datetime": "2023-03-18 17:20:00",
"channels": 11,
"channels_out": 10,
"channels_in": 1
},
{
"datetime": "2023-03-18 17:10:00",
"channels": 11,
"channels_out": 10,
"channels_in": 1
},
....
]

Real-Time Calls in Progress

/v3/voice/{ACCOUNT}/inprogress/current

GET
Number and value of calls in progress relative to account balance. Useful for fraud monitoring.

{
"datetime": "2014-02-30 12:34:35",
"total": 1.164,
"callcount": 107,
"balance": 24.406,
"percent_available": 0.25,
"approx_seconds_remaining": 56838,
"calls": {
"1739": {
"location": "UK - Fixed",
"country": "GB",
"total": 0.85,
"callcount": 85
}, "2303": {
"location": "UK - Mobile - T-Mobile",
"country": "GB",
"total": 0.244,
"callcount": 19
}, "277": {
"location": "Mexico - Mexico City",
"country": "MX",
"total": 0.04,
"callcount": 2
}, "2761": {
"location": "Spain - Mobile - Telefonica",
"country": "ES",
"total": 0.02,
"callcount": 1
} },
"countries": {
"MX": {
"total": 0.04,
"callcount": 2
},
"ES": {
"total": 0.02,
"callcount": 1
},
"GB": {
"total": 1.094,
"callcount": 104
}
}
}

As of version 3.15 this information is now also able to be pushed directly to you via Webhooks, for more information see https://cdn.simwood.com/docs/simwood_webhooks_beta.pdf

The above example shows many calls in progress to the UK, along with two to Mexico (MX) and one to Spain (ES) - calls are grouped both by destination (keyed by a unique numeric identifier for that destination) in then "calls" group and by country in "countries" - this makes it simple to alert, for example, if there are any more than a predefined number of calls to any country you don’t expect.

See http://blog.simwood.com/2014/01/2-quick-scripts-to-help-you-sleep-easier/ for some examples of how this data can be used to help protect you against fraud and monitor your VoIP traffic.

Call Control

/v3/voice/{ACCOUNT}/inprogress/{CALL_ID}

Get information on current call in progress
{
"success": true,
"data": {
"to": "447700900123",
"start": "2019-09-23 12:27:12",
"progress": "2019-09-23 12:27:17",
"answered": "2019-09-23 12:27:21",
"destid": "2303"
} }

End a call in progress
{
"success": true
}

GET
DELETE

This is designed to be used in conjunction with the Webhook HTTP Events (Beta) detailed at https://cdn.simwood.com/docs/simwood_webhooks_beta.pdf

The {CALL_ID} in the above URL is the call_id element in the JSON objects you receive for call_inbound, call_outbound and inprogress_calls HTTP Webhook events posted to your platform.

As this is a BETA endpoint, the information returned from the above may change at any time, although we will endeavour to ensure backwards compatibility therefore, whilst parameters will be added, it is unlikely that any of the above will be removed.

Voice CDRs (Inline Response)

In addition to the CDR Reports (above) you can retrieve any CDRs from the last three months with a simple inline response (rather than polling for a report)

/v3/voice/{ACCOUNT}/cdr

MethodDescription
GET/POSTBoth GET and POST are supported. The request can either be made as a GET query string or JSON POST body. At present, the filter attribute is only supported where requested by POST with a JSON body.
date_startOptionally specify date/time in YYYY-MM-DD HH:ii:ss format to request report from date_start, otherwise defaults to start of current day.
NB Dates must be specified in GMT, within the last 90 days
date_endOptionally specify date/time in YYYY-MM-DD HH:ii:ss format to request report from date_end, otherwise defaults to now.
limitOptionally specify limit of results to return, default 500
startOptional offset to start from (for pagination)
filterObject of "search_key" => "value" e.g. {"trunk": "930000- TEST"} would return CDRs only for the trunk named "930000- TEST".
At present you can filter only on the following values, more will be added in the future; from, to, toISO, trunk, tag

/v3/voice/{ACCOUNT}/cdr/{YYYY-MM-DD}

MethodDescription
GET/POSTAs above, a shorthand way of retrieving CDRs for a particular day. The date must be within the last 90 calendar days
limitOptionally specify limit of results to return, default 500
startOptional offset to start from (for pagination)
filterAs above

/v3/voice/{ACCOUNT}/cdr/{YYYY-MM-DD}/{REFERENCE}

GETRetrieve more information, where available, on a specific call using the reference value returned from the above CDRs (or the CDR Reporting)

This function is temporarily unavailable as of version v3.10.5

NB date_start and date_end must be within the last 90 calendar days

Rejected Calls

When calls are rejected by Simwood for any reason (e.g. exceeding a channel limit, invalid CLI information, or because they are on a blacklist or your own do not call list) no CDR is generated and, therefore, they cannot be retrieved with the above endpoints.

These rejections are notified using the notification endpoint you have configured (e.g. by eMail or HTTP post) Additionally, the most recent rejections can be retrieved from the following API endpoints.

/v3/voice/{ACCOUNT}/rejected


{
"success": true,
"data": [
{
"calldate": "2016-02-08 07:00:04",
"reason": "maxcost",
"from": "441632496000",
"to": "447700900123",
"message": "Call to 447700900123 will exceed 0.1 ( 0.25450 )",
"source_ip": "10.0.0.0",
"trunk": "9XXXXX-L001",
"notified": false
}
]
}
GET Get all available recently rejected calls

/v3/voice/{ACCOUNT}/rejected/{REASON}

GETAs above, but an optional REASON is specified to return only rejections of the specified reason (e.g. "maxcost" or "cli")

NB Rejection data should be considered ephemeral. In any event the above endpoints will never return more than data from the current day and the preceding day.

Voice Trunks

NB Trunks were previously located at /v3/voice/{ACCOUNT}/outbound however this endpoint, along with its related sub-resources, are now deprecated in favour of the new, more appropriately named /v3/voice/{ACCOUNT}/trunks resource. The original endpoint(s) will remain in order to preserve backwards compatibility, however they will not benefit from any of the new inbound-specific options.

Trunk Management

Trunks should following the naming ACCOUNT-{ID} e.g. if your account is 930004 and the trunk for ACME Products you could name the trunk 930004-ACMEPRODUCTS.
The "L001" trunk is your default IP-Authenticated trunk and cannot be renamed, additionally there are some features (Trunk Balances, Realtime Trunk Calls in Progress etc) that are not available on the L001 trunk.

/v3/voice/{ACCOUNT}/trunks

GETList all active outbound trunks.

/v3/voice/{ACCOUNT}/trunks/{TRUNK}

MethodDescription
GETRequest information on specified {TRUNK}
PUTCreate new trunk {TRUNK}
NB for an ‘auth’ trunk the SIP password will be returned ONLY as a response to this API call and cannot be retrieved later. If you forget the password it can be reset as described below (Trunk Password Functions)

or (if additional optional configuration parameters specified, see overleaf)

Update existing {TRUNK} settings such as channel and rate limits

When creating a new trunk, the type can be one of;
IP create an IP-authenticated Trunk
auth create a username/pass authenticated trunk. for compatibility, if not specified defaults to 'auth'
DELETEDelete trunk {TRUNK}
NB the default trunk {ACCOUNT}-L001 cannot be deleted

Newly created trunks are available for use immediately although, at times, may not show in the outbound trunk list for a short time.

Trunk Options

/v3/voice/{ACCOUNT}/trunks/{TRUNK}

MethodDescription
PUTUpdate existing {TRUNK} settings such as channel and rate limits
The options below are only to be used when updating an existing trunk
enabled
[optionala]
Enable [1] or Disable [0] this trunk.
NB this takes precedence over in/out below
enable_in
[optional]
Enable [1] or Disable [0] inbound calls on this trunk (when being used via SIP registration)
enabled_out
[optional]
Enable [1] or Disable [0] outbound calls on this trunk.
limit_concurrent_*
[optional]
The * above to be replaced by one of the parameters opposite
Concurrent channel limit for the class of calls indicated as an integer value or [null] (do not impose a limit)
out out_international
out_international_hotspot out_per_number in
limit_rate_*
[optional]
Rate limit for each of the above outbound categories in the form calls/duration (or [null] where no limit) e.g.
5/10s 5 calls per 10 seconds
100/12h 100 calls in 12 hours
NB The timeframe must be one of [ 12h | 10s | 1s ]
cli_format
[optional]
For inbound calls associated with this trunk, receive the CLI in the selected format, one of [ e164 | +164 | uk | us ]
cli_default
[optional]
Default Presentation Number to be presented when no valid CLI is provided or cli_force_default set (E164 format)
cli_force_default
[optional]
Set to [1] to force above value to be used on all calls. [0] allows customer-specified CLI
nni_default
[optional]
Default Network Number to be used when required must be a number on your account in E.164 format (e.g.441632960123)
max_cpm
[optional]
Maximum cost per minute (in your billing currency) of the B leg of the call. Using this can help ensure a customer trunk cannot make calls to expensive destinations
max_cpc
[optional]
To be used in conjunction with the above, sets a maximum connection cost per call.
max_cost
[optional]
Sets a maximum cost per call, i.e. when the cost of the call reaches (approximately) this amount it will be cleared
max_dur
[optional]
Sets a maximum duration per call, when the call reaches this duration, it will be cleared.
emergency_enabled
[optional]
Set to [1] to enable emergency calls (requires account activation)

NB If you update a trunk and one or more parameters are invalid, the update will succeed with the valid parameters, please check the output returned and ensure the trunk is configured as you expect.

Please note that all trunk settings are updated immediately, therefore disabling (e.g. by setting enabled = 0) is an effective way to block any further calls being made on a trunk. It will not stop calls currently in progress.

Trunk Balances

Each trunk can have its own balance, this allows you to manage the spend of individual customers. You can also view "inprogress" information for a trunk which will show the value of calls in progress. Where the value of calls in progress exceeds the trunk balance, calls in progress will be ended.

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/balance

MethodDescription
GETGet Balance for {Trunk}
PUTSet or adjust the balance for {TRUNK}
balance - Sets the balance of the trunk to balance
-or-
adjust - Adjust the trunk balance by the amount shown, use negative amounts to decrement the balance.
GETRemove the balance from trunk {TRUNK}
NB The trunk will function as before, without it’s own balance, so will be limited only by your account balance or balance lock
This is NOT EQUIVALENT TO setting a balance to 0 which would prevent further calls being made (i.e. Balance exhausted)

The trunk balance feature is provided for convenience and is not a substitute for your own billing and credit control procedures. Simwood will not be liable for any calls made on a trunk when its trunk-specific balance is depleted for any reason.

Set balance on trunk 920123-ACME to £200
{"balance": 200}

We strongly recommend that "balance" is used to set an initial balance only, and thereafter the level is maintained using the "adjust" function.

Adjust balance on trunk 920123-ACME by £50 (e.g. if Customer has topped up)
{"adjust": 50}
Adjust balance on trunk 920123-ACME by £20 (e.g. to deduct supplementary services)
{"adjust": -20}

NB Your account primary -L001 IP trunk does not support Trunk Balances.

Per-Trunk Realtime Call Information

As with your account you can also view realtime "in progress" information on a per-trunk basis. /v3/voice/{ACCOUNT}/trunks/{TRUNK}/inprogress


{
"datetime": "2014-02-30 12:34:35",
"total": 1.164,
"callcount": 107,
"balance": 24.406,
"percent_available": 0.25,
"approx_seconds_remaining": 56838,
}
GETProvides information on the calls currently in progress on the specified TRUNK

Where a trunk has a balance the three additional elements will be present which have the same meaning as in your account snapshot but pertain only to the TRUNK specified;

balance, percent_available, and approx_seconds_remaining

These are omitted where a trunk has no balance, but you can still view the current value of calls in progress.

NB Your account primary -L001 IP trunk does not support this feature.

Trunk IP Functions

The following applies only to trunks using IP-Based authentication, your primary trunk ({ACCOUNT}-L001) is an example of one such trunk which does not require a SIP username and password.

Please ensure you only add IP addresses that you control and DELETE any that are no longer required.

Please note that that this functionality should NOT be used to update an account with dynamic IP addresses - such installations, where unavoidable, should use authenticated SIP trunks as described above.

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/acl
GETRequest a list of IP address authorised on ip-based {TRUNK}

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/acl/{IP}
PUTAdd {IP} to ip-based {TRUNK}
DELETERemove {IP} from ip-based {TRUNK}

Trunk Password Functions

The following applies only to authenticated trunks (those using a username and password) or being used for SIP registration.

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/password_reset


{
"updated":true,
"trunk":"{TRUNK}",
"user":"{TRUNK}",
"pass":"e5d5aca5e39251bdc19554d3"
}
POSTRequest and return a new password for this trunk.
NB The old password will be disabled immediately, any devices configured to use this trunk will need reconfigured to continue to make outbound calls.

NB It is not possible to specify a password for a trunk, they are automatically generated.

Likewise, the Operations Desk cannot recover a forgotten password, the only facility they have is to reset the password using the above functionality. Please keep your password(s) safe.

Outbound Destination Prefix ACLs

Not to be confused with IP ACLs (to determine which IPs can make outbound calls on a particular trunk) Destination Prefix ACLs allow you to limit access on a per-account of per-trunk basis to certain destinations.

The ACL is specified in a JSON-encoded object as follows;

allow Array Allowed Prefixes e.g. [441,442,443,448]
deny Array Denied Prefixes e.g. [44870]

This would be encoded in JSON as follows;

{"allow":[441,442,443,448],"deny":[44870]}

This example would allow calls to all UK Geographic, 03 Numbers and all 08 Numbers except 0870.


Please note
(1) Longest prefix matching is used, so 44870 in the **deny** list will block even if 448 is allowed.
(2) If only **allow** is specified, this is treated as a whitelist. all other destinations will be denied.
(3) If only **deny** is specified, this is treated as a blacklist. all other destinations will be allowed.
(4) Account-level blocks will override any trunk settings. (e.g. a trunk cannot call a destination blocked at the account level)
(5) Trunk level blocks will override any account-level allows. (e.g. you may deny certain trunks access to destinations that are otherwise allowed)

/v3/voice/{ACCOUNT}/outbound/destinationacl

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/destinationacl

MethodDescription
GETRetrieve active ACL on your account or trunk as specified
PUTReplace active ACL with the JSON object PUT.
The preferred method of doing this is to send the new ACL as the body of the PUT request, however if your implementation does not support this you may send the entire string in a single HTTP form encoded variable ‘payload’
DELETERemove the ACL associated with the account or trunk
Please note that the default is to allow access to ALL destinations without restriction - please ensure this is what you want.

Calls rejected due to failing a destination ACL rule will have the following X-Reason headers set in the SIP response to the initial INVITE;
X-Reason: 447700900123 matches trunk do not route 447
X-Reason: 449098790000 matches customer do not route 449

Either one of these may have (cached) appended where the number has been blocked more than once in the last 60s, in such case the prefix may not be shown.

NB The above ‘destination acl’ function is provided on a ‘best-efforts’ basis and is not intended as a substitute for securing your own VoIP platform. You remain responsible for all calls made on your account.

Trunk Routing Configuration

It is now possible to set a trunk-level routing configuration which will be used for any numbers associated with it (and not having their own configuration) - this is ideal for customers who send calls for a group of numbers to one destination, and another group of numbers to a different destination.

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/config
GETReturn configuration for {TRUNK}
PUTReplace active configuration with the JSON object PUT.
DELETERemove configuration for {TRUNK}

For full syntax and available options please refer to Number Routing Configuration below.

Bulk Number Association

As detailed below, inbound numbers can be associated with a trunk either for billing purposes only, or to make use of its additional controls and/or routing configuration (where one does not exist on the number itself). These associations can be created individually by updating each number as required, or where multiple numbers are to be associated with the same trunk, it can be performed in a single request using the following endpoint.

NB If a number has its own specific routing configuration, then any trunk association defined in the ‘options’ block will continue to take priority.

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/numbers
GETReturn the currently associated numbers
{ "success": true, "data": [ "443301223000", "443301223001", "443301223002", ... ] }
PUTAssociate more numbers to the trunk, passing the numbers you wish to append as an array, per the example below
{ "data": [ "443301223003", "443301223004", "443301223005", ... ] }
POSTReplace the list of associated numbers entirely, passing the numbers you wish to replace it with as an array. Passing an empty array will remove any direct associations with this trunk.
NB All existing associations with this trunk will be removed!
{ “data”: [ “443301223100”, “443301223101”, “443301223102”, ... ]}

When associating numbers to a trunk, any individual routing configuration currently set on those numbers will need to be removed if your intention is for the configuration of the newly associated trunk to be followed. You can do this for each number individually using the number’s own configuration endpoint, or alternatively, if you wish to remove all number-level configuration at the same time as associating with the trunk, you can include the optional force property:

 {
"data": [
"443301223100",
"443301223101",
"443301223102",
...
],
"force": true
}

NB Force removal of configs in this way is irreversible and if done so unintentionally, will need to be added back one by one!

IDA Outbound Management

You can access your outbound SIP rates from any* standard BT landline using our shared IDA code 12940. Access is restricted to authorised CLIs.

IDA users are managed much like trunks (see above), each number added automatically creates a ‘trunk’ in the form {ACCOUNT}-IDA01xxxxxxxxx, you will see these identifiers as the trunk in your CDRs and the same settings can be applied as to trunks (see above) ||/v3/voice/{ACCOUNT}/ida| |:-|:-| |GET|Retrieve active IDAs on your account|

/v3/voice/{ACCOUNT}/ida/{CLI}
GETRetrieve the details associated with this IDA User
PUTCreate a new IDA user with the specified {CLI}
or (if additional parameters are supplied)
update an existing IDA user (see above "Trunk Management" for an example of what parameters are available)
DELETEDelete the IDA user with the specified {CLI}

Users making calls using the IDA service should dial the full number prefixed with 12940 e.g. to call 029 2120 2120 you would dial 1294002921202120

  1. At present you cannot associate more than one CLI with a single IDA ‘trunk’

  2. If another Simwood customer has enabled a CLI for the IDA service you will not be able to associate the same CLI with your own account.

* Some landlines may not permit IDA calls

IDA for Virtual Interconnect ("Hosted IDA") Virtual Interconnect - Inbound customers using their own IDA codes should not use the above functionality. Please contact us for more information on IDA for Virtual Interconnect.

Inbound Numbering

Number Allocation

UK Number Ranges

/v3/numbers/{ACCOUNT}/ranges


{
"success": true,
"data": [
{
"id": "03dd542cafcecf43fc06024ee6099311424c71cf",
"prefix": "113403",
"sabc": "1134",
"description": "Geographic - Leeds",
"chargeband": "geo"
},
{
"id": "3d80bd92a9ba2ca31c646881127d322a",
"prefix": "113499",
"sabc": "1134",
"description": "Geographic - Leeds",
"chargeband": "geo"
},
...
]
}
GETetrieves a list of all available UK number ranges, including descriptions. This is intended for customers to populate, for example, a drop down to allow customers to select an area
NB This does not return international numbering at this time.

Available Numbers

/v3/numbers/{ACCOUNT}/available/[all|gold|standard]/[1|10|100]
GETReturns 1,10 or 100 numbers available for allocation matching the pattern specified.
One of all, gold, or standard should be specified in the URL;
all returns all available numbers matching pattern
gold returns only gold numbers matching pattern
standard returns only non-gold numbers matching pattern
pattern
Search for numbers matching specified pattern (can use wildcards e.g *203*)
NB For backward compatibility, please note that if country_code is not set, a search for 4420* and 20* are identical and are assumed to be UK numbers (without the leading 0). Similarly, a search for 1212* will be assumed to be the UK (0121 2*), NOT the USA 1-212.
country_code
Optional country code, currently only one of [1|44] Defaults to 44 for UK numbering, use 1 for USA numbering.
[{ "country_code":"44", "number":"1134032330", "recommended_gold_premium": 0, "wholesale_gold_premium" 0, "block":"03dd542cafcecf43fc06024ee6099311424c71cf", "bill_class":"Carrier", "SMS": 0 }]

/v3/numbers/{ACCOUNT}/available/consecutive/[10|20|30|40|50|60|..100]
POSTRequest a report of 10,20,30,40,50,60,70,80,90 or 100 consecutive numbers available for allocation matching the pattern specified.
NB This function currently does not support country_code or non UK searches
pattern Search for numbers matching specified pattern (can use wildcards e.g 203)

Please note the above options (e.g. 1|10|100) are the only options, arbitrary values (e.g. /25) are not supported.
NB Some number types, e.g. OTT Mobile Numbers are only available as gold numbers at this time.

Allocated Numbering

/v3/numbers/{ACCOUNT}/allocated/all
POSTRequest a report of all current allocated numbers on account.
patternOptionally specify to include only those numbers that match the specified pattern(can use wildcards e.g *203*)
keyOnly return those numbers that match the specified key in their metadata (see Advanced Routing below)
NB Keys are case-insensitive, wildcards not supported.
filter_configOnly return numbers that have their own individual routing configuration.

/v3/numbers/{ACCOUNT}/allocated/[10|100|1000|10000]
POSTRequest a report of the first [ 10 | 100 | 1,000 | 10,000 ] numbers that match the optional pattern.
patternOptionally specify to include only those numbers that match the specified pattern(can use wildcards e.g *203*)
keyOnly return those numbers that match the specified key in their metadata (see Advanced Routing below)
NB Keys are case-insensitive, wildcards not supported.
filter_configOnly return numbers that have their own individual routing configuration.

Please note the above options (e.g. 1|10|100) are the only options, arbitrary values (e.g. /25) are not supported.

GETReturn configuration information on allocated {NUMBER}
PUTAllocate an available {NUMBER} to the account
DELETEDe-configure and irrevocably remove {NUMBER} from account

$ Gold Number Activation Fee Where {NUMBER} is a Gold Number an activation fee will be charged

$.. Number Rentals There is an ongoing monthly fee for geographic numbers, please see https://simwood.com/rates for more information

Last Call

/v3/numbers/{ACCOUNT}/allocated/{NUMBER}/lastcall

{
"success":true,
"data": {
"calldate":"2017-05-01 12:34:01",
"cli":"07700900123",
"disposition":"NORMAL_CLEARING",
"billsec":"64",
"duration":"68"
} }
GETReturns a JSON object describing the most recent call to this number

Number Routing Configuration

Introduced in May 2014, the following is the preferred way of configuring a number, the previous method is still detailed in this document but is deprecated and will be removed in a future revision of the API.

When a new configuration is provided this will take precedence over any existing configuration.

/v3/numbers/{ACCOUNT}/allocated/{NUMBER}/config

GET Return configuration information on allocated {NUMBER} See Configuration Syntax (New) below


{
"routing": {
"default": [
[
{
"type": "sip",
"endpoint": "441632960000@pbx.simwood.com"
},
{
"type": "reg",
"user": "930XXX-SIPUSER"
}
],
[
{
"type": "pstn",
"number": "447700900123"
}
]
]
}
}
MethodDescription
PUTReplace active configuration for {NUMBER} with the JSON object PUT.
The preferred method of doing this is to send the new routing configuration as the body of the PUT request, however if your implementation does not support this you may send the entire string in a single HTTP form encoded variable ‘payload’
{"success": true}
If any error(s) occurred whilst validating the configuration these will be shown;
{ "success": false, "errors": [ "Message #1", "Message #2" ] }
DELETEDe-configure the configuration of {NUMBER}
NB if configuration is still present on the /voice endpoint, it will be used

Similarly, it is now possible to set a trunk-level configuration which will be used for any numbers associated with it (and not having their own configuration) - this is ideal for customers who send calls to a group of numbers to a single destination, and another group of numbers to a different destination.

/v3/voice/{ACCOUNT}/trunks/{TRUNK}/config
GETReturn configuration for {TRUNK}
PUTReplace active configuration with the JSON object PUT.
DELETERemove configuration for {TRUNK}

Lastly, the default configuration will be used for all numbers on your account where no other configuration exists - this is ideal for customers who send all calls to a SIP URI and handle onward routing themselves
/v3/numbers/{ACCOUNT}/default/config
GETReturn default number configuration for {ACCOUNT}
PUTReplace active default configuration with the JSON object PUT
DELETERemove default configuration

Number Configuration Syntax - Advanced

NB The syntax described in this section applies equally to number, trunk, and default configuration endpoints.

Numbers are configured using a JSON object which is described below, offering increased flexibility over the previous route configuration.

An example (annotated) configuration is below, and the full list of options can be found overleaf.

"rules": {
"mon__fri_0700__1700": [
{
"dow": [1,2,3,4,5],
"time": ["0700","1700"]
}
]
},

Rules define times of day that routing blocks (below) apply, outwith the rules given - or if the rules section is omitted entirely - the default routing block will be used.
"routing": {
"mon__fri_0700__1700": [
[
{
"type": "reg",
"user": "939998-FREDTEST",
"timeout": 30,
"sdes": "optional",
"opus": "default"
}
],
This block will run during the officehours time block defined above (Mon-Fri 9am-5pm) and will call the SIP endpoint shown and the user on the registration proxy simultaneously.
    [
{
"type": "sip",
"endpoint": "%e164@pbx.mycompany.com",
"timeout": 30,
"sdes": "none",
"opus": "default"
}
],
[
{
"type": "pstn",
"number": "447405644486"
}
]
],
After the timeout above (30s) we will try the PSTN number provided
    "default": [
[
{
"type": "pstn",
"timeout": 30,
"number": "447405644486",
"trunk": "939998-ALAUTHTEST"
}
]
]
},
The default routing block will be used outwith the office hours specified above. So calls outside of normal office hours will be forwarded directly to the PSTN number shown.
"options": {
"enabled": true,
"block_payphone": false,
"acr": false,
"icr": false,
"beta_in": true
},
Per number configuration options (detailed above) apply to the number at all times
    "meta": []
}
The meta block contains arbitrary metadata that you want to associate with the number

Number Configuration Syntax

"options"

The following options can be set on a per-number basis, they apply to the entire configuration at all times

OptionDescription
enabled[true|false]Allows number to be disabled [false] without removing the configuration.Default [true]
block_payphone[true|false]Prevents inbound calls originating from payphonesDefault [false]
acr[true|false]Apply ACR to this number. ACR Prevents calls originating from Withheld numbers reaching this number. Withheld callers will be diverted to a recorded announcement.Default [false]
trunk9XXXXX-TRUNKAssociate a trunk with this number for billing purposes ONLY, shown in CDRs.

NB This does NOT result in the number being routed to a registration-based SIP trunk. You would need to use the appropriate ‘reg’ routing block.

You can also configure this using the endpoint /v3/numbers/[ACCOUNT]/allocated/ {NUMBER]/trunk.

This option is only relevant for number-level configuration.
Default [9XXXXX-L001] or your account default inbound trunk if different.

$.. Chargeable Options

Some options may incur additional monthly fees. Please see https://simwood.com/rates for full information

"rules"

The ‘rules’ parameter in the JSON object should be an array of named objects (named using the characters a- z and the _ character only) each of which defines a time period using the following parameters;

Parameterdescription
dowArray of values [1..7]The days of week this rule is active (according to ISO 8601) e.g. 1 = Monday, 7 = Sunday.
NB if one day must still be an array. e.g. [3] not 3
timeArray [start,end]Array of two values, denoting the start and end time this rule applies in 24h format (e.g. [0900,1700] would represent 9am - 5pm. The leading 0 can be omitted)
dayArray of values [1..31]The days of month this rule is active NB if one day must still be an array. e.g. [25] not 25
monthArray of values [1..12]The months this rule is active
e.g. 1 = January, 12 = December.
NB if one day must still be an array. e.g. [3] not 3

Example

Office HoursMon - Fri
0900-1700
"rules": {
"officehours": [
{
"dow": [1,2,3,4,5],
"time": [900,1700]
} ]
}
WeekendsSat/Sun
(All Day)
"rules": {
"weekend": [
{
"dow": [6,7]
} ]
}
Christmas / New Year
Dec 25th
December 26th
January 1st
January 2nd
"rules": {
"christmasholiday": [
{
"month": [12],
"day": [25,26]
},{
"month": [1],
"day": [1,2]
}
] }

"routing"

Much like the rules above the ‘routing’ property is an array of objects named corresponding to the rules. There is also the special ‘default’ rule, which applies when there are no rules specified or outwith the times specified in the rules.

NB This property is mandatory and submitted config will be rejected without it.

Routing blocks (described below) can be arranged to allow dialling in parallel or in sequence, or a combination of both as shown below;

Ring A & B simultaneously, Then C

"routing": {
"officehours": [
[
{
BLOCK A },
{
BLOCK B
} ],
[
{
BLOCK C }
] ]
}

Ring A, B and C simultaneously

"routing": {
"officehours": [
[
{
BLOCK A },
{
BLOCK B
}, {
BLOCK C }
] ]
}

Ring A, then B, then C

"routing": {
"officehours": [
[
{
BLOCK A },
], [
{
BLOCK B
} ],
[
{
BLOCK C }
] ]
}

"meta"

The ‘meta’ parameter in the JSON object allows you to store your own arbitrary data in the Simwood database associated with a number and which can be easily accessed via the API.

The key parameter can be used to search for number(s) matching a specified key, the rest of the object is freeform up to a size limit of around 512 bytes.

keyString[40 chars]A (non-unique) key for this number which you can use to search for matching numbers, most commonly customers use this to store a representation of their own customer account ID or username.
NB Keys are treated as case-insensitive
....The rest of the meta parameter can be composed of ANY valid JSON structure, some example uses are given below.

Examples

In this example the key is used to store the customer account ID. The friendlyName is used to allow the customer to assign a memorable name to the number in the customer interface. The lastUpdated parameter is used to show when a number was last updated.
"meta": {
"key": "403010",
"friendlyName": "Main office number",
"lastUpdated": "2014-02-30 01:20:30"
}
In this example the key is used to store the customer eMail address and a password. This could be used to build a simple portal for managing forwarding of one number (e.g. a personal number redirection service)

NB This illustrates a potential use only - please do NOT store clear text passwords in this manner.
"meta": {
"key": "customer@example.com",
"pass": "secretWord"
}
This shows how this could be used to store a note associated with a number that hasn’t been configured yet.
"meta": {
"notes": "This is reserved for Brian at
Example Corp and is not yet in use",
"reserved": true
}

The flexibility offered by the "meta" block enables customers to build a full service (e.g. offering number translation services, fax to eMail or similar) without requiring a local database.

NB Meta attributes are intended for API use only and are NOT displayed in the portal. These attributes may be overwritten if a number is later configured using the portal.

Routing Block

Each routing block is defined by a minimum of a ‘type’ and some optional parameters delay and timeout;

parametervalues
typesipSIP endpoint
regRegistered SIP user
pstnPSTN Destination (i.e. voice call forwarding)
faxReceive as Fax to eMail or HTTP
NB fax cannot be used in conjunction with any other endpoint
busyBusy tone
delay[1...n]Delay before executing this leg
timeout[1...n]Timeout for answer from this leg Not supported by busy or fax endpoints

NB A number can be configured for either voice or fax routing It is not possible to simultaneously use the same number for voice and fax.

Routing Block Additional Parameters

Depending on the type of endpoint selected above there are some additional endpoint-specific mandatory and optional parameters;

typeparameter
sipendpointSIP Endpoint (user@host.com with optional :port and ;transport parameters e.g. %164@example.com:5060;transport=tcp) the following substitutions will take place;
%e164 will be replaced with the full number in E164 format
%ukn will be replaced with the number in UK National format
sdesOne of optional, required, or none. If optional we will offer SDES encryption for the audio on inbound calls. If set to required, the call will not complete without successful negotiation of SDES. If not specified, or set to none, SDES will not be offered by default.
opusOne of never, always, or only. Override the default handling of Opus offers in INVITEs to your platform;

never will suppress the Opus codec from the SDP, which may be useful for UDP destinations to prevent long INVITEs becoming fragmented as Opus does typically increase the SDP payload by around 220 bytes.
always will always offer the Opus codec, together with the usual codec offering of G.722 and G.711, in the SDP.
only will offer the Opus codec only, excluding all other codecs. This is ideal if your platform uses Opus and you can support Opus for all calls, and still keeps the SDP to a size that is unlikely to result in fragmentation
zoneOne of our zone names [slo, lon, ny or sj]..

If present, calls originating in the specified zone will be passed to this endpoint, overriding any equal priority endpoints without a zone specified.
This can be used together with multiple sip endpoints to ensure that calls are routed in the most efficient way depending on where they ingress the Simwood network. e.g. calls arriving in London, will route to your own local proxy.
This will be particularly useful to customers with direct connections to Simwood, or hosting their own equipment on- net.

NB if a call originates from any zone which matches an endpoint with a specific zone set, then any other endpoints within that group will be disregarded.
If the call originates from a zone which does not match a specific endpoint, any endpoint without a zone parameter will be used.
There must always be one endpoint at the same level with no zone specified.
reguserSIP registration user (e.g. 9xxxxx-USERNAME)
sdesOne of optional or required. Defaults to optional, we will offer SDES encryption for the audio on inbound calls to registered endpoints. If set to required, the call will not complete without successful negotiation of SDES.
opusOne of never, always, or only. Override the default handling of Opus offers in INVITEs to your platform;

never will suppress the Opus codec from the SDP, which may be useful for UDP destinations to prevent long INVITEs becoming fragmented as Opus does typically increase the SDP payload by around 220 bytes.
always will always offer the Opus codec, together with the usual codec offering of G.722 and G.711, in the SDP.
only will offer the Opus codec only, excluding all other codecs. This is ideal if your platform uses Opus and you can support Opus for all calls, and still keeps the SDP to a size that is unlikely to result in fragmentation
NB if the user is not registered at the time the call is received this will be skipped entirely, we advise you use another destination (or ‘busy’) in addition to a reg endpoint.
pstnnumberDestination number in e164 format (e.g. 447700900123)
NB the pstn divert function is intended for voice calls only.
maxcpmMaximum cost per minute (in your billing currency) of the B leg of the call, intended for use with NTS services to limit exposure to expensive destinations or to ensure that the destination number cost is covered by the revenue share from the inbound leg. (e.g. 0.05)
maxcpcTo be used in conjunction with the above, sets a maximum call cost (e.g. connection cost)
NB does not limit call duration to a cost ‘limit’
cliCLI to present when forwarding the call, if not specified will present the callers CLI where it is available.
trunkThe trunk to be associated (for billing and CDR purposes) with the outbound (B-leg) (e.g. 9xxxxx-TRUNKNAME)
faxmethodOne of http or mail
endpointDestination eMail address or HTTP POST URI e.g. user@host.com http://www.yourdomain.com/cgi/inboundfax.php
busyno parameters available

NB The ‘pstn’ endpoint is intended for voice calls only. We cannot guarantee successful transmission of fax or data calls forwarded to the PSTN using this functionality.

Number Configuration Worked Examples

Call user@host.com over SIP for 20s, then try 447700900123 with custom CLI

{
"routing": {
"default": [
[
{ "type": "sip","endpoint": "user@host.com","timeout": 20 }
],
[
{ "type": "pstn","number": "447700900123","cli": "442921202120","maxcpm": 0.02}
]
]
}
}
Forward all calls to 447700900123

{
"routing": {
"default": [
[
{
"type": "pstn",
"number": "447700900123"
} ]
] }
}
Forward all calls to SIP endpoint

{
"routing": {
"default": [
[
{
"type": "sip",
"endpoint": "%did@sip.mycompany.com"
} ]
] }
}

The above might seem complicated but corresponds to the following simple PHP example, which illustrates the underlying structure;

PHP Example of above

<?php
// Define the route
$arrayRouteDefinition = Array('type' => 'sip', 'endpoint' => ‘%did@sip.mycompany.com’);
// Add it to the ‘default’ routing block
$arrayRouting['default'][] = Array($arrayRouteDefinition);
// Add the routing configuration to the config
$arrayConfig['routing'] = $arrayRouting;
// encodedConfig now contains the JSON encoded routing
$encodedConfig = json_encode($arrayConfig);

Another advantage of this method is that you can retrieve the configuration as a JSON object via your favourite programming language, edit the required entry in place and PUT the changed configuration back.

Number Configuration - Success

Changes should take effect immediately, and the following simple JSON object will be returned;

successtrueWill always be true when the routing has been successfully updated.

Number Configuration - Errors

In the event of a configuration error a simple JSON object will be returned as follows;

successfalseWill always be false where any error was present.
Your config will NOT have been changed.
errorsArrayThis will contain an array of human-readable errors each will include an indication of where the error was in your structure. A non-exhaustive list of these are below.

NB Where any error is present in the configuration the extant configuration will remain in place even if only one element has an error, the entire configuration will be rejected.|

Setting ‘OPTION’ must be X, Y or ZAn option in the "options" section has an invalid value, please select from one of the provided values
Invalid parameter ‘OPTION’ in settingsA parameter in the "options" section is unrecognised. please remove this parameter
Rule name ‘NAME’ is invalid.Rule names must contain the characters shown only
[RuleRouting Block] must be an array.
Rule ‘NAME’ entry X parameter ‘PARAM’ is invalid.The value provided for the parameter in the rule shown is invalid.
Routing block 'NAME' does not match any specified rules (or default)A routing block has been specified that doesn’t correspond to any time-dependant rules (or "default") - therefore would never be called. Check your rule names match.
Unknown section ‘NAME’ in configuration.There is a section that is unrecognised, if you wish to store your own information in a number configuration you may do so but this must be within the ‘meta’ section (which can contain anything)

Inbound Trunk Association

Inbound numbers can be associated with a trunk either for billing reconciliation purposes only, or to take advantage of some of the trunk-specific controls and/or routing configuration for inbound traffic. If a number- level configuration exists then this will take priority over any trunk-level configuration, which in turn, will take priority over the default account-level configuration.

NB This does NOT result in the number being routed to a registration-based SIP trunk. You would need to use the appropriate ‘reg’ routing block in either the Number or Trunk Configuration as shown above.

/v3/numbers/{ACCOUNT}/allocated/{NUMBER}/trunk

JSON response

{
"success": true,
"data": {
"trunk": "930XXX-ACMEPRODUCTS"
} }
GET

Get the trunk currently associated with this number


{
"success": true,
"data": {
"trunk": "930XXX-ACMEPRODUCTS"
}

}
PUTAssociate this number with a trunk
JSON requesttrunkThe trunk to associate with this number
DELETERemove the association with the trunk

Mobile Number Inbound SMS Configuration

NB Only mobile or OTT numbers can be configured for inbound SMS.

UK Mobile Numbers will be able to receive SMS (this includes both OTT numbers and MSISDNs obtained from Simwood, as well as SMS to numbers ported-in) - you can deliver these over HTTP to your own platform.

/v3/numbers/{ACCOUNT}/allocated/{NUMBER}/sms

JSON response


{
"success": true
}
GET

Request current inbound SMS configuration for the provided number


{
"success": true,
"data": {
"mode": "http",
"endpoint": "http://api.yourdomain.com/path/to/mtsms.cgi"
}
}
PUTUpdate SMS configuration for the provided mobile number
JSON requestmode

One of [ http | http_json ] Both use the HTTP method, however http posts data to your script as application/x-www-form-urlencoded (much like a typical HTML <form> would). This is now considered a legacy configuration and does not support modern TLS endpoints or Unicode messaging.

http_json makes an HTTP POST request with Content-type application/json with the body of the request as a JSON document (described below) - this is the preferred mode.
Only the http_json method supports TLS endpoints.
endpointOnly where mode is ‘http’ or 'http_json'An HTTP(S) URL that will receive a POST request for each SMS sent to this number.
NB only the http_json method supports TLS endpoints.
{
"mode": "http_json",
"endpoint": "https://secure.api.yourdomain.com/path/to/mt"
}
DELETEDelete SMS configuration for this number

Number Configuration - 999 Emergency Services

/v3/numbers/{ACCOUNT}/allocated/{NUMBER}/999

MethodDescription
GETReturn current 999 information for {NUMBER}
PUTReplace current 999 details on {NUMBER}
Please note maximum field lengths indicated below
title20Individual End User Only
Title (e.g. Mr, Ms, Mrs)
Titles that disclose gender are preferred by the Emergency Services.
GET

Return current 999 information for {NUMBER}

PUT

Replace current 999 details on {NUMBER} Please note maximum field lengths indicated below

title20Individual End User Only
Title (e.g. Mr, Ms, Mrs)
Titles that disclose gender are
preferred by the Emergency Services.
forename20Individual End User Only
Forename or Initials
name50Individual End User Only
Surname
Business End User
Business Name [See Note 1]
bussuffix50Business End User Only
Suffix (Ltd, Plc) [See Note 2]
premises60Mandatory for Individual and Business End Users
Identifies premises on a thoroughfare i.e. House Number
or Name (e.g. 104, The Lighthouse, Thatched Cottage)
thoroughfare55Mandatory for Individual and Business End Users
Street Name
(e.g. King Street, Station Road, Beech Avenue)
locality30Mandatory for Individual and Business End Users
Village or an area within an Town and Town if possible
postcode12Mandatory for Individual and Business End Users
The full current postcode as recognised by Royal Mail’s
PAF database. This must be in the form Out-code space In
code e.g. LS11 5DF, S9 5AD, S60 3ML

Remember this information is to assist the Emergency Service response and you have a legal obligation to ensure this information is provided fully and accurately to the best of your ability.

The name and address information should be sufficient to identify the premises or individual promptly in an emergency. This is more important than it matching the ‘official’ record; for a business entry include only the business details, do NOT specify your contact there or primary account holder etc as an individual.

Note 1 : Business Names Business names should be chosen that best allow the Emergency Services to identify and locate the business - typically this is the ‘name over the door’ rather than that of a parent or holding company irrespective of who you address the bill to.

Note 2 - Business Suffix Addition to business name (e.g. Ltd or Plc) this can also be used to include a brief description that identifies the function of the business - e.g. "Hospital", "Hotel", "Fuel Storage Depot" provides valuable extra information to the Emergency Services

$ Submission Charge There is a charge for this service. Please see https://simwood.com/rates for full information

Number Validation

We provide a simple API endpoint to allow you to determine if a particular number is in a valid format and is suitable for use as valid Caller ID.

This endpoint also provides other useful information about the number, such as the original Carrier (if known), Country, Type of Number, and information from the local authority (e.g. Ofcom) where possible.

/v3/numbers/{ACCOUNT}/validate/{NUMBER}

GET

Validate the number provided (number should be in e.164 format) ( e.g. the following result would be obtained from a GET request to /v3/numbers/{ACCOUNT}/validate/443301223000 )

{
"success": true,
"data": {
"valid": true,
"country_code": "44",
"iso": "gb",
"national_number": "3301229999",
"type": "uan",
"carrier": "Simwood",
"timezones": [
"Europe\/Guernsey",
"Europe\/Isle_of_Man",
"Europe\/Jersey",
"Europe\/London"
],
"formatted": {
"e164": "+443301229999",
"national": "0330 122 9999",
"international": "+44 330 122 9999"
}, "ofcom": {
"status": "allocated",
"use": "national non-geographic",
"rh": "Simwood eSMS Limited",
"date": "2010-07-20",
"valid_cli": true
} }
}

For UK numbers, the ofcom->valid_cli parameter can be used to determine if this number would be accepted as valid Caller ID in the UK in accordance with Ofcom policy and General Condition C6. This takes into account numbers (such as 09) which are valid numbers, but cannot be used as Caller ID.

NB This is not a "live" lookup like an HLR lookup or look-ahead routing lookup, the indication that a number is 'valid' here solely confirms it appears to formatted correctly and does not indicate if the number is in service. Furthermore, the carrier, where present, will reflect the original carrier of the number if a number has been ported to a new operator.

Number Lookup

We provide a simple API endpoint to allow you to look up the rangeholder information for a particular number or number range.


This may be of use to customers looking to port numbers, however it should be noted that if a number has previously been ported the LCP may not be the rangeholder
GET

Lookup information on the number provided (number should in e.164 format) ( e.g. the following result would be obtained from a GET request to /v3/numbers/{ACCOUNT}/lookup/443301223000 )

{
"success": true,
"formatted": "+44(0)330 1223000",
"data": {
"code": "3301",
"prefix": "330122",
"rh": "Simwood eSMS Limited"
} }

Number Porting

Ports can be submitted, and viewed via the API.

There are different endpoints (and data required) depending on the type of port, it is imperative you use the correct endpoint for the type of port requested.

type of numberport type
UK Geographic Numbers
01xxxxxxxxx
02xxxxxxxxx
GNPGeographic Number Porting is outlined in our Geographic Number Portability Guide.
Numbers can be ported from most major fixed-line and VoIP service providers and lead times are subject to the type of port.
You must have authority from the end user to port a number, and evidence of this may be requested.
UK Mobile Numbers
07[1-9]xxxxxxxxx
MNPMobile Number Portability is managed differently from GNP.
Numbers can be ported from all UK MNOs and MVNOs and the port will typically take 2-3 days. The active mobile service (and SIM) associated with the number will cease when the port completes.
MNP requires a "PAC" (Porting Authorisation Code) to authenticate the porting request. This is provided to the existing subscriber by their Mobile Service Provider. This code must be provided at the time of porting.
PACs are valid for 30 days.
UK Non-Geographic Numbers
03xxxxxxxxxx
08[457]xxxxxxx
At present, these numbers cannot be ported via the API.
Some NGNs are portable, please contact the Porting Desk.
UK Premium Rate Numbers
070xxxxxxxx
09xxxxxxxxx
At present, these numbers cannot be ported

Update December 2016

Please note that there are now two endpoints listed for each GNP API function as follows

/v3/porting/{ACCOUNT}/ports

/v3/porting/{ACCOUNT}/gnp

We strongly recommend use of the /gnp endpoint for consistency with the new porting types, however the /ports endpoint provided historically will remain in service for backward compatibility.

Geographic Number Porting ("GNP")

New GNP [Geographic Number Porting] Submission

/v3/porting/{ACCOUNT}/ports

/v3/porting/{ACCOUNT}/gnp

POST
Submit a new Geographic Number port. The following must be submitted as a JSON object, an example is below
mbnMain Billing Number (MBN) in UK (01xxxxxxxxx) format
orig_refFor resubmissions only, the original order reference
lcpLosing Communications Provider (e.g. "BT")
lcp_cupid

The numeric CUPID of the LCP or hosting network, see the /porting/{ACCOUNT}/lcps endpoint (detailed below)

port_date
(Optional)
Porting date (CRD) in form YYYY-MM-DD HH:mm:ss
Please see minimum lead times below.
If omitted, will port as soon as possible.
contact_emailA contact eMail address for the port (note this must be the address of the submitter NOT your customer\)
account_numberThe account number with the LCP (if known)
billing_postcodeThe postcode associated with the current installation This MUST match the records held by the LCP
typeOne of the port types listed below (e.g. "single")
linesNumber of lines in the existing installation
channelsNumber of channels in the existing installation
customerobject*

This must be a JSON object containing each of the elements described below
NB This is NOT the same as 999 above.
numbersarray*

An array of "number" objects, see below

Submission Charge There is a charge for this service. Please see https://simwood.com/rates for full information

Port Types

Each port will be one of the following types, if unsure please contact the LCP before submission. Subsequent ports must be used where the number is already ported (i.e. the LCP is not the rangeholder) Please observe the lead times in the Number Portability Guide when specifying a port_date.

singleSingle Line - 4 Working Days (14 if > 10 lines porting in same installation/time)
multiMulti Line - 7-17 Working Days (dependant on number of lines/numbers, see guide)
sub_singleSingle Line - 7 Working Days (17 if > 10 lines porting in same installation/time)
sub_multiMulti Line - 10-25 Working Days (dependant on number of lines/numbers, see guide)

The above is provided for guidance only, the Number Portability Guide should be consulted to determine lead times for porting requests.

Number Object

The ‘numbers’ array in the above should be an array of objects each with the following structure. These must include all numbers, including the MBN (even though it is specified separately)

ParameterValues
number01xxxxxxxxx
02xxxxxxxxx
Number in UK National format
typembnMain Billing Number (must only be one of this type)
associatedAssociated Number (e.g. another DDI on an ISDN circuit)
otherOther Number at the same address (but not associated)
actionportPort this number to Simwood
retainRetain service on this number as-is (only for ‘other’ type)
dropDrop this number and cease service on the porting date

Customer Object

parametermax length
title20Individual End User Only
Title (e.g. Mr, Ms, Mrs)
Titles that disclose gender are
preferred by the Emergency Services.
forename20Individual End User Only
Forename or Initials
Business End User
Forename/Initials of Signatory
name50Individual End User Only
Surname
Business End User
Surname of LoA Signatory
company50Business End User
Business Name
bussuffix50Business End User Only
Suffix (Ltd, Plc)
premises60Mandatory for Individual and Business End Users
Identifies premises on a thoroughfare i.e. House Number
or Name (e.g. 104, The Lighthouse, Thatched Cottage)
thoroughfare55Mandatory for Individual and Business End Users
Street Name
(e.g. King Street, Station Road, Beech Avenue)
locality30Mandatory for Individual and Business End Users
Village or an area within an Town and Town if possible
postcode12Mandatory for Individual and Business End Users
The full current postcode as recognised by Royal Mail’s
PAF database. This must be in the form Out-code space In
code e.g. LS11 5DF, S9 5AD, S60 3ML

New Port Submission - Full Example

JSON of example porting request

{


"mbn": "01632960100",
"contact_email": "simwood.customer@example.com",
"lcp": "BT",
"lcp_cupid": "001",
"account_number": "NA1234B32",
"billing_postcode": "A12 3BC",
"type": "multi",
"lines": 1,
"channels": 30,
"customer": {
"title": "Mr",
"forename": "John",
"name": "Doe",
"loa_initial": "J",
"loa_surname": "Doe",
"premises": "123",
"thoroughfare": "Some Street",
"locality": "Sometown",
"postcode": "A12 3BC"
},
"numbers": [
{"number": "01632960100", "type": "mbn", "action": "port"},
{"number": "01632960101", "type": "associated", "action": "port"},
{"number": "01632960102", "type": "associated", "action": "port"},
{"number": "01632960103", "type": "associated", "action": "port"},
{"number": "01632960104", "type": "associated", "action": "port"},
{"number": "01632960105", "type": "associated", "action": "port"},
{"number": "01632960106", "type": "associated", "action": "port"},
{"number": "01632960290", "type": "other", "action": "retain"}

]

}

Response The response will be a JSON similar to the following;

       {
"success": true,
"ref": 12345,
"url": "/v3/porting/{ACCOUNT}/ports/12345"
}

The "ref" value corresponds to the ticket that will be used to track the progress of the porting request. If any error(s) occurred whilst validating the configuration these will be returned as follows;

       {
"success": false,
"errors": [ "Message #1", "Message #2" ]
}

Port Resubmissions

When resubmitting a previously rejected port, please use the original porting order number in the orig_ref parameter to ensure your port is processed and billed correctly at the reduced rate for resubmissions.

NB Failure to provide this will result in the port being processed as a new order and the normal porting fees applicable to the order type will apply.

View Port List

/v3/porting/{ACCOUNT}/ports

/v3/porting/{ACCOUNT}/gnp

{
"success": true,
"data": [ {
"ref": "54721"
"mbn": "01632960100",
"date": "2015-02-29",
"crd": "2015-03-14",
"status_code": "submitted_rh"
"status": "Submitted to RH"
}, {
... }
] }
GETGet a list of currently outstanding, or recently completed (within the last 90 days) geographic number ports

View Port Status

/v3/porting/{ACCOUNT}/ports/{ORDER_REFERENCE} /v3/porting/{ACCOUNT}/gnp/{ORDER_REFERENCE}

{
"success": true,
"data": {
"mbn": "01632960100",
"status": "Porting Request Received",
"status_code": "rcvd",
"contact_email": "your.name@example.com",
"lcp": "BT",
"rh": "BT",
"account_number": "NA1234B32",
"billing_postcode": "A12 3BC",
"type": "multi",
"lines": "1",
"channels": "1",
"customer": { ... },
"numbers": [ ... ],
"events": [
{
"date": "2015-02-29 13:33:51",
"status_code": "submitted_lcp",
"status": "Submitted to LCP",
}, {
"date": "2015-02-29 14:23:51",
"status_code": "accepted",
"status": "Porting Request Accepted",
},
{
"date": "2015-02-29 13:33:51",
"status_code": "rcvd",
"status": "Porting Request Received",
"info": "Order Submitted by API"
}
]
}
}


GETGet full detail as submitted, and history, of a port The customer and numbers elements will be returned as originally submitted but are omitted here for clarity. The events element contains a chronological history of the port.

View Porting LCPs

To be used when submitting new porting requests, this endpoint provides a list of available LCPs and the corresponding CUPIDs.

This endpoint provides a list of all CPs with which we have established non-geographic porting agreements. It is worth noting, however, that there may be other rangeholders we can port from where their range is hosted by one of the CPs in this list.

/v3/porting/{ACCOUNT}/lcps

{
"success": true,
"cps": [
{
"cpName": "BT",
"cupid": "1"
},
{
"cpName": "Telephony Services",
"cupid": "93"
},
{
"cpName": "Gamma Telecom",
"cupid": "31"
} ]

}

GETGet list of LCP (Losing Communications Providers) we can port from and the corresponding CUPIDs

NB When providing a CUPID in the API you can use either an integer (e.g. 1) or conventional format of the three digit string value (e.g. 001 for BT)

When submitting a porting request where a number is hosted by a different network, please provide the CUPID of the hosting network (e.g. an ITSP using Telephony Services for number hosting should have the lcp_cupid provided as "093")

Mobile Number Porting ("MNP")

New MNP [Mobile Number Porting] Submission

/v3/porting/{ACCOUNT}/mnp

{
"success": true,
"data": {
"pac": "ABC1234567",
"msisdn": "447700900123",
"date_port": "2016-12-16",
"ref": 43001
} }
POSTSubmit a new Mobile Number port.
msisdnMSISDN (mobile number) in E.164 format e.g. 447700900123
pacPAC for this number (e.g. ABC1234567)
contact_emailA contact eMail address for the port (note this must be the address of the submitter NOT your customer)
port_date
[Optional]
Porting date (CRD) in form YYYY-MM-DD If omitted, will port as soon as possible.
(two working days from today)

he "ref" value returned corresponds to the ticket that will be used to track the progress of the porting request.

$ Submission Charge There is a charge for this service. Please see https://simwood.com/rates for full information

View Port List

/v3/porting/{ACCOUNT}/mnp

{
"success": true,
"data": [
{
"pac": "ABC1234567",
"msisdn": "447700900123",
"date_added": "2016-12-06",
"date_updated": "2016-12-06",
"date_port": "2016-12-08",
"status_code": "pending"
"status": "Pending"
"ref": 43001
},
{
...
}
]
}
GETGet a list of currently outstanding, or recently completed mobile number ports

View Port Status

/v3/porting/{ACCOUNT}/mnp/{PAC}

GETGet details of an MNP porting request
{
"success": true,
"data": {

"pac": "ABC1234567",
"msisdn": "447700900123",
"date_added": "2016-12-06",
"date_updated": "2016-12-06",
"date_port": "2016-12-08",
"status_code": "pending"
"status": "Pending"
"ref": 43001
}
}

MNP Exports

At this time it is not possible to generate a PAC from the API. Please raise a ticket via https:// support.simwood.com/ or by eMail to team@simwood.com to request a PAC for an MSISDN you have imported.

Fax and SMS Messaging

Inbound Fax Retrieval

Faxes received on your Simwood numbers can be retrieved via the API for a period of seven days from receipt and can be queried via the API

/v3/fax/{ACCOUNT}/inbound/[{NUMBER}]

GETLists las secen days of inbound faxes (optionally filtered by NUMBER)
{
"success": true,
"data": [
{
"hash": "7e2bb7bb87300ff83c657b04b07b8261"
"time": "2015-02-30 12;34:56",
"originator": "07700900123",
"destination": "443301223000",
"station": "MYFAX",
"duration": 31,
"pages": 1,
"url": "/v3/..../7e2bb7bb87300ff83c657b04b07b8261.pdf"
} ]
}

/v3/fax/{ACCOUNT}/inbound/{NUMBER}/{HASH}

GETRetrieve specific fax in PDF format, where NUMBER is the destination fax number and HASH is the hash in the HTTP POST request made to your platform, or in the list retrieved above.
DELETEForce deletion of the specified fax HASH received on NUMBER. Faxes will be automatically deleted after seven days if not manually deleted.

Outbound SMS

/v3/messaging/{ACCOUNT}/sms

POSTSend an SMS Message
toRecipient in e164 format (e.g. 447700900123)
fromOriginator number in e.164 format or alpha-numeric (maximum 11 characters if alphanumeric)
messagePlain text message to send
flash
[optional]
Defaults to 0. If set to 1 message is sent as a ‘flash’ message (i.e. it will be displayed on the phone screen but not stored in the recipient’s inbox, subject to handset and network support)
replace
[optional]
Defaults to 0. If set to 1 message is sent with an instruction to the handset to replace the previous. This must be set to 1 on both the original and replacement message.
concat
[optional]
An integer defining the maximum number of SMS to send to deliver your message where it is too long for the normal 160 plain text character limit of a single SMS. The default value of 1 will truncate your message if it is longer than 160 characters unless you set this parameter to a higher value.
report
[optional]
URL for delivery report. The following placeholders can be used;
%id%Message ID
%status%Status Code
extended
[optional]
If set (1) will return extended information as below. This is not enabled by default to ensure backward compatibility

If successful the message will be queued immediately and an id returned as follows; If the extended parameter is included, additional information will be included in the response e.g;

[{"id":"02f150a0690171038624cc9d0e89207d"}]
{
"success":true,
"data":{
"id":"1f40b0ac384cab838acf39a0e3e38bba",
"desc":"SMS - United Kingdom",
"parts":1,
"charge":0.02,
"currency":"GBP"
}
}

$ Message Charge There is a charge for sending SMS messages. Please see https://simwood.com/rates for full information

Outbound FAX

/v3/messaging/{ACCOUNT}/fax

POSTSend an Fax
to[]Recipient number in e164 format (e.g.447700900123)
This parameter may be repeated multiple times, the [] are part of the parameter name and must be included.
fromOriginator number in e.164 format.
file[]The PDF file to send. Please note that as of v3.9 only PDF is supported and this must be POSTed as a file (per RFC1867) (e.g. using an HTML form input type of "file") with mime type application/pdf

Despite the inclusion of [] in the name, this parameter cannot be repeated multiple times, however the [] are part of the parameter name and must be included.
sendat[optional] Defaults to immediate, but a future date can be specified in the form YYYY-MM-DD hh:mm:ss
priority
[optional]
Jobs in the queue are processed in order of priority, then by submission date. Billing also depends on priority. 10 is default, less than 10 being more urgent, more than 10 being non-urgent.
report
[optional]
URL for delivery report. The following placeholders can be used;
%id%Message ID
%status%Status Code

If submission is successful, the fax will be queued immediately and response returned as an array containing the number and corresponding id of the submitted fax for each destination number;

[{"number":"441632000123","id":"b902e8e46b91900af276f52995a3082e"},
{"number":"447700900123","id":"71cea3179fdd13271a2ac14a366941f8"}]

Fax Content Types

To ensure faxes arrive as intended, all faxes should be sent in PDF format with an application/pdf mime type.

$ Message Charge There is a charge for sending fax messages. Please see https://simwood.com/rates for full information

HTTP POST (Inbound Events)

Certain commands enable us to send data to your system over HTTP(S) in response to events rather than commands. These events are:

  • Fax received on a number configured for HTTP POST
  • SMS received on a number configured for HTTP POST
  • The status of outgoing SMS messages
  • The progress of outgoing faxes

In all cases the message will be sent to the URL you specified and will intelligently retry until a HTTP response with a status code of 200 and a non-zero length body is returned in response, which indicates success.

Your application must therefore raise an error code in the HTTP header (e.g. 500) in the event of a problem rather than a plain text message in the body of the response. All responses are discarded.

Event-driven Webhooks

There are now a number of event-driven webhooks available which provide realtime information on calls in progress, incoming and outgoing calls, along with call rejections and other account-wide events. For more information see https://cdn.simwood.com/docs/simwood_webhooks_beta.pdf

Received Fax

When a fax is received on a number configured to relay them by HTTP POST you will receive an HTTP POST message with a single parameter payload containing a JSON-encoded representation of the following;

Description
app‘fax_inbound’ in this case. This is to facilitate re-use of the same status receiver your side for multiple applications.
hashThe unique hash for the fax, used as a reference and to retrieve the fax
dataAn object containing the following parameters:
idUnique ID for the fax
timeTime fax was received (in form YYYY-MM-DD HH:mm:ss)
originatorThe CLI of the calling fax machine (if available)
destinationThe destination number (i.e. the Simwood number that received the fax)
status_msgA human readable status message (e.g. "Ok")
status_codeThe above in a form which should be quoted on any ticket raised.
bpsThe speed of fax receipt in bits per second.
stationIf present, the CSID of the remote fax machine.
durationThe billable time (in seconds) used to receive the fax.
pagesThe number of pages received
url

The URL where the fax (in PDF format) can be retrieved, takes the form https://api.simwood.com/v3/files/{ACCOUNT}/fax-NNNNNNNNNNNNNNNNN

Please note that faxes expire for your own security You must request the PDF from the URL provided within 5 minutes from successful receipt of the notification

Received Fax (Beta)

When a fax is received on a number configured to relay them by the http_json method you will receive an HTTP POST message of Content-type application/json with the following JSON body;

Your endpoint can support (or require) TLSv1.1, TLSv1.2. Please note that SSLv3 and TLSv1 are not supported by this service.

Description
app‘fax_inbound’ in this case.
NB This field exists to facilitate re-use of the same status receiver your side for multiple applications. However as this is a beta this is subject to change and it is strongly recommended to use a dedicated URL to receive HTTP requests.
idA unique ID representing this request e.g. fi_422296075c882529362765a39aa75b19
dataAn object containing the following parameters:
idUnique ID for the fax
timeTime fax was received (in form YYYY-MM-DD HH:mm:ss)
originatorThe CLI of the calling fax machine (if available)
destinationThe destination number (i.e. the Simwood number that received the fax)
status_msgA human readable status message (e.g. "Ok")
status_codeThe above in a form which should be quoted on any ticket raised.
bpsThe speed of fax receipt in bits per second.
stationIf present, the CSID of the remote fax machine.
durationThe billable time (in seconds) used to receive the fax.
pagesThe number of pages received
url

The URL where the fax (in PDF format) can be retrieved, takes the form https://api.simwood.com/v3/files/{ACCOUNT}/fax-NNNNNNNNNNNNNNNNN

Please note that faxes expire for your own security You must request the PDF from the URL provided within 5 minutes from successful receipt of the notification

Received SMS (http) - Deprecated

When an SMS is received on a number configured to relay them by using the legacy http method you will receive an HTTP sPOST message of Content-type application/x-www-form-urlencoded with a single parameter payload containing a JSON-encoded representation of the following;

Please note your endpoint cannot require TLSv1.1 or higher. The legacy SMS service supports SSLv3 and TLSv1 only (or plain http) for TLS support please use the service described below (with type http_json)

Description
app‘mvno_inbound_sms’ in this case.
This is to facilitate re-use of the same status receiver your side for multiple applications.
idA unique ID representing this request e.g. fi_422296075c882529362765a39aa75b19
dataAn object containing the following parameters:
timeTimestamp of message (in form YYYY-MM-DD HH:mm:ss) Where available from the originating network.
originatorThe MSISDN or Originator of the SMS message
destinationThe destination number (i.e. the Simwood number that received the SMS)
messageThe content of the SMS message
lengthTThe length (characters) of the SMS message.

For your security we do not retain message content after relay to your own platform

Received SMS (http_json)

When an SMS is received on a number configured to relay them by using the http_json method you will receive an HTTP POST message of Content-type application/json with the following JSON body;

Your endpoint can support (or require) TLSv1.1, TLSv1.2.
Please note that SSLv3 and TLSv1 are not supported by this service.

Description
app‘sms_inbound’ in this case.
NB This field exists to facilitate re-use of the same URL for multiple applications. However we strongly recommended to use a dedicated URL where possible.
idA unique ID representing this request e.g. fi_422296075c882529362765a39aa75b19
dataAn object containing the following parameters:
timeTimestamp of message (in form YYYY-MM-DD HH:mm:ss) Where available from the originating network.
originatorThe MSISDN or Originator of the SMS message
destinationThe destination number (i.e. the Simwood number that received the SMS)
messageThe content of the SMS message
lengthTThe length (characters) of the SMS message.

An example full message is shown below

{
"app": "sms_inbound",
"id": "si_422296075c882529362765a39aa75b19",
"data": {
"originator": "447700900321",
"destination": "447700900123",
"length": 12,
"message": "Hello World."
}
}

For your security we do not retain message content after relay to your own platform

Outbound Fax Reports

Where a report field was specified for an outgoing fax, we will make a POST to the URL specified. If present, ‘%id%’ in your URL will be replaced by the message ID returned in the response below and ‘%status%’ will be replaced with the status code.

Additionally the POSTed data will contain a single parameter called payload, the value of which will be a JSON encoded representation of the following.

Description
app‘fax_inbound’ in this case.
This is to facilitate re-use of the same status receiver your side for multiple applications.
idThe unique id for the fax returned when it was submitted.
dataAn object containing the following parameters:
dtimeThe date/time the status was generated.
statusA numeric indication of status. There will typically be three.
1 Queued: The fax has been queued to the fax server. For scheduled faxes this will happen at the specified time.
5 Processing: We have begun conversion and transmission of fax
10 OK: Fax transmission completed successfully >10 Fax transmission may not have completed successfully, please see the status_msg and supplementary fields for more details.
status_msgA human readable status
stationIf present, the CSID of the remote fax machine.
durationTThe billable time (in seconds) spent on your fax. Note, as we employ an intelligent retry system this may be the sum of several transmissions.
errorsThe number of transmission errors.
urlThe number of retries required.

Outbound SMS Delivery Reports (DLRs)

Where a report field was specified for an outgoing SMS, we will make a POST to the URL specified. If present, ‘%id%’ in your URL will be replaced by the message ID returned in the response below and ‘%status%’ will be replaced with the status code.

Additionally the POSTed data will contain a single parameter called payload, the value of which will be a JSON encoded representation of the following.

FieldDescription
app‘sms_send_status’ in this case. This is to facilitate re-use of the same status receiver your side for multiple applications.
idThe unique id for the SMS returned when it was submitted.
dataAn object containing the following parameters:
dtimeThe date/time the status was generated. Note, this is the time the status was generated or received by Simwood. For example, in the case of a delivery report it will not the time of actual delivery but the time we learned of delivery.
statusA numeric indication of status. There will typically be three for SMS.

1 Received: This will be raised immediately the SMS is committed to a queue at Simwood. Generally this will be simultaneous with your message submission but messages will be queued between the API and Simwood systems for performance.

2 Submitted: The SMS has left Simwood. Again, this will generally coincide with your submission and status 1 above but queueing at every stage affords scalability and performance enhancement.

11 Delivered: Confirmation received from the handset of delivery. Generally this will be 4 seconds or so after the above for a handset in signal.

12 Rejected: Message was rejected, has not been delivered and will not be retried.

13 Error: There was a syntax error with the message, usually relating to invalid destination address but in some cases disallowed source address.

14 Queued: Message has been buffered for delivery in transit. This usually indicates the phone is off or out of service coverage.

18 SMSCa: Message has been accepted by the SMSC. For networks where delivery reports are unavailable, this is the closest status to a delivery receipt.

26 SMSCr: Message was rejected by the SMSC and will not be retried.

Change Log / Document History