Browse the documentation

Documentation

Getting started

This guide takes you from no account to a first analyzed call in eight steps: create an account, find your ingress address, whitelist the IP your switch sends from, set a destination, choose a plan, point a trunk at the ingress, place a test call and read the verdict. Nothing registers and nothing authenticates with a password — Open Voice Shield authorizes your traffic by source IP.

Before you start#

Open Voice Shield sits between your switch and wherever the call was already going. You keep your carrier, your numbers and your dial plan; you change one route so the calls you want analyzed traverse us first.

You need four things:

  • A switch, PBX or SBC that can send SIP to a fixed peer with no registration and no credentials — authorization is by source IP.
  • The public IP address that switch sends from (the address after NAT).
  • A destination — the SBC, PBX or carrier we hand the call on to. It has to accept SIP and RTP from our address.
  • Firewall access, so you can open the ports in step 2.

We are in the media path

The RTP flows through our media address in both directions — that is how the call gets recorded, and there is no analysis without a recording. If your audio must never leave your own network, this is not the right product for you.

Step 1 — Create your account#

Sign up at /signup with your work e-mail, a password of at least 12 characters, and your company name. The account is usable immediately: it starts on Pay-as-you-go with a prepaid balance of zero, so top it up or subscribe before you place the test call in step 7.

The same thing over the API#

create an account and keep the access token

API=https://your-ovs-host.example        # your API base URL

curl -s -X POST $API/api/auth/signup \
  -H 'Content-Type: application/json' \
  -d '{"email":"ops@acme.example","password":"correct-horse-battery","company":"Acme Call Center"}'
# 201 {"customer":{"id":"...","plan_code":"payg","ports":4,"balance":0.0,...},
#      "access_token":"...","token_type":"bearer","expires_in":900}

TOKEN=...                                # the access_token above

The access token is short-lived. For anything that runs unattended, create a long-lived API key instead and send it as X-API-Key:

an API key — the full key is shown once, at creation

curl -s -X POST $API/api/auth/api-keys \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"crm-integration"}'
# 201 {"id":"...","name":"crm-integration","prefix":"ovs_...","key":"ovs_...","revoked_at":null}

If your operator created the account for you

Accounts created by an operator are issued a temporary password and flagged for a password change. Every endpoint outside /auth/* answers 403 password_change_required until you set a new one — the portal routes your first sign-in straight to that screen.

Step 2 — Find your ingress address#

The Network page of the portal shows the address to send SIP to. The same values come from the API:

GET /customer/network-info

curl -s $API/api/customer/network-info -H "Authorization: Bearer $TOKEN"
# {"ingress_host":"192.0.2.10","ingress_port":5060,"transports":["udp","tcp"]}
The response fields. 192.0.2.10 is a documentation address — use the one your own account returns.
FieldMeans
ingress_host The host your switch sends the INVITE to. It is also the source address of everything we send onward, so your destination must trust it.
ingress_port The SIP port, 5060.
transports The SIP transports we accept: udp and tcp. Pick one. TCP is the safer choice when your INVITEs carry large SDP.

Open the firewall, both directions#

Signalling and media use different ports, and the media leg is the one people forget. Media is plain RTP on a UDP range at the same address; the range is 30000–40000 unless your operator says otherwise.

Firewall rules on your side of the connection.
Direction Protocol and ports Why
Out, to the ingress host UDP or TCP 5060 Your INVITEs, and your OPTIONS keepalive.
Out, to the ingress host UDP 30000–40000 Your RTP towards us.
In, from the ingress host The SIP port of your destination We relay the call onward from our own address, so the destination has to accept SIP from it.
In, from the ingress host Your destination's RTP range The media we relay onward also comes from our address.

If the destination is your own SBC or PBX, add the ingress host to its trusted peers or ACL now. Skipping this is the most common reason a first test call is rejected by your own equipment rather than by us.

Step 3 — Whitelist the IP your switch sends from#

There are no SIP credentials. We accept a call only when its source address is on your whitelist, so add the public address your PBX or SBC sends INVITEs from — the address after NAT, not the private one on its interface.

POST /customer/ips

# one host
curl -s -X POST $API/api/customer/ips \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"cidr":"198.51.100.7/32","label":"PBX egress"}'
# 201 {"id":"...","cidr":"198.51.100.7/32","destination_id":null,"enabled":true,...}

# a whole site, sent to its own destination
curl -s -X POST $API/api/customer/ips \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"cidr":"198.51.100.0/28","label":"site B","destination_id":"<destination id>"}'
The rules the whitelist enforces.
RuleDetail
FormatCIDR. A single host is /32 (IPv4) or /128 (IPv6).
Widest accepted/16 for IPv4, /48 for IPv6. Anything broader is refused as too broad.
ExclusivityA range belongs to one account platform-wide. Overlapping a range already registered to another account returns 409.
Overlap within your accountWhen several of your entries match, the longest prefix wins — so a /32 can override the destination of a wider range.
How manyUp to 50 entries per account.
Turning one offenabled: false keeps the entry but stops accepting calls from it.

Step 4 — Tell us where to send the call next#

A destination is where an authorized call goes after we have accepted it: usually the same SBC, PBX or carrier the traffic was already reaching. Add one and mark it as the default.

POST /customer/destinations

curl -s -X POST $API/api/customer/destinations \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"host":"203.0.113.10","port":5060,"transport":"udp","is_default":true,"label":"main SBC"}'
  • host is a public IP or a resolvable hostname. Loopback, link-local and multicast addresses are refused, and so are private ranges in production.
  • transport is udp, tcp or tls, and is independent of the transport your switch uses towards us.
  • Up to 20 destinations per account.

When a call arrives we pick its destination in this order, highest first:

  1. a routing rule whose prefix is the longest leading match of the dialed number;
  2. the destination attached to the whitelist entry that matched the source IP;
  3. your default destination;
  4. failing all of those, back to the source address on 5060/udp.

Prefix routing rules are how you send one range of dialed numbers somewhere else — a test range, or a voice agent — while everything else follows the default. Setting them up is covered in the SIP integration guide.

Step 5 — Choose a plan#

Your plan decides two things that matter on day one: how many calls you can have up at once (ports), and what a minute costs. A new account is on Pay-as-you-go. Plans are public, so you can read them before you sign up:

GET /plans — the public plan list

curl -s $API/api/plans
# [{"code":"payg","name":"Pay-as-you-go","monthly_fee":0.0,"ports":4,
#   "included_minutes":null,"per_minute_rate":0.035,"min_billable_seconds":60,
#   "active":true,"description":"No monthly fee. $0.035 per analyzed minute, billed per second after 60s."},
#  ...]
What each field on a plan controls.
FieldControls
portsConcurrent calls. Call number ports + 1 is rejected with 486.
monthly_feeThe subscription fee, charged against your balance. Zero on Pay-as-you-go.
included_minutesMinutes covered by the fee each month. null means none — every minute is charged.
per_minute_rateThe rate per analyzed minute, and the overage rate once included minutes are used up.
min_billable_secondsThe minimum billed duration of an answered call.

POST /customer/plan — subscribe

curl -s -X POST $API/api/customer/plan \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"plan_code":"starter"}'
# 402 if the balance does not cover the first month's fee; 409 if you are already on that plan

Current prices, with the date they were read from the live API, are on the pricing page. Calls are admitted only while your balance covers at least one minute, so keep credit on the account before you test.

Step 6 — Point a trunk at the ingress#

Create an IP-authenticated trunk, peer or carrier entry on your switch with these settings, then route the traffic you want analyzed through it — a dial pattern, one queue, one campaign, or everything.

Trunk settings on your switch, whatever it is called there.
SettingValue
Peer host / proxyyour ingress_host
Port5060
TransportUDP or TCP
Authenticationnone — by source IP
Registrationoff. A REGISTER is answered 403; we are a proxy, not a registrar.
CodecsPCMU and/or PCMA at 8 kHz; telephone-event may be offered
SDPin the initial INVITE. An INVITE with no SDP is answered 488.
SRTP / TLS mediaoff — plain RTP
ICEoff; we strip it from the SDP
KeepaliveSIP OPTIONS, answered 200 OK
Called numberthe user part of the Request-URI
Caller ID (ANI)the user part of the From header — this is what automation rules act on

Codecs decide whether you get an analysis at all

Calls that negotiate anything other than G.711 are still relayed and still billed, but they cannot be transcribed, so no analysis is produced. Offer PCMA and PCMU and let us record what you already carry.

Keep your existing direct route in place as a fallback. If the ingress ever answers 503, you want the call to take the old path rather than fail.

Step 7 — Place a test call#

  1. Check reachability. Send SIP OPTIONS from your switch to sip:ping@<ingress_host>:5060. We answer 200 OK from any address — this proves the network path and the port, not the whitelist.
  2. Place a real call through the new route, with at least 30 seconds of two-way speech. Say something a fraud analyst would recognize as ordinary business conversation.
  3. Talk in both directions. A leg that never speaks shows up as a one-sided transcript.

If the call is rejected, the response code says which check failed:

What we answer when a call cannot be accepted.
ResponseCauseFix
403Source IP not whitelisted, account suspended, or the ANI is under an active block controlStep 3, or release the control under Automation
402Prepaid balance will not cover a minuteTop up, or subscribe to a plan
486Already at your plan's concurrent call limitWait, or move to a plan with more ports
488The INVITE carried no SDPSend an early offer
503We could not accept or relay the callRetry on your fallback route, then check Troubleshooting

Very short calls are billed but not analyzed: below the minimum analysis length (5 seconds by default) the call record is marked as skipped.

Step 8 — Read the verdict#

Within about a minute of hang-up the call record carries a transcript and an analysis. Open it in Calls in the portal, or fetch it:

GET /calls — the most recent calls, with the analysis summary

curl -s "$API/api/calls?limit=5" -H "Authorization: Bearer $TOKEN"
# {"total":1,"items":[{"id":"...","status":"completed","billsec":42,
#   "transcript_status":"done","analysis_status":"done",
#   "analysis":{"probability":12,"category":"legitimate_business","recommendation":"allow",...}}]}
The fields you will look at first.
FieldWhat it tells you
analysis_statusdone means there is a verdict. skipped means the call was too short; an error value points at the reason.
probability0–100. How likely this call is fraudulent or non-compliant.
recommendationblock review allow — the action being suggested to a human.
categoryWhat kind of call it looks like: impersonation, tech support scam, compliant telemarketing, legitimate business, and so on.
red_flagsThe specific observations behind the score — urgency, fear tactics, harvesting personal data, no opt-out offered.
tcpa_commentThe TCPA-relevant findings on the call, in plain language.

A verdict is an aid for a reviewer, not a judgment. Read the transcript before acting on a score — the recording, the transcript, the SIP ladder and a pcap of the call are all on the call record, and can be exported together for offline review.

You are already alerted on the worst of them#

Every new account is created with one alert rule enabled, High-risk fraud alert (default): any call scoring 90 or above and recommended block is e-mailed to your account address. It is an ordinary rule — change its thresholds and recipients, or switch it off, under Alerts.

What to do next#

  • Move beyond one trunk: transports, prefix routing and the full SIP behaviour are in the SIP integration guide.
  • Learn what every analysis field means before you build a workflow on it — Concepts.
  • Push verdicts into your own systems with webhooks and the API.
  • Something rejected or missing an analysis? Troubleshooting lists the codes and the checks that clear them.