Port Scan API
Scan for Open Ports and Their Services on Demand.
POST a target and the ports you care about. The API scans the host in real time and returns each TCP and UDP port it found with its state and service, plus versions and the operating system when you ask for them.
Request
POST /
Body {"tcp_ports": "80,443",
Response · 200 OK
-
target_ip104.26.11.21
-
tcp- 80open · http
- 443open · https
service_productandservice_versionnull when the service does not reveal them -
udp[]
Only scan hosts you own or are authorized to test.
check_date 2026-09-22T16:06:23Z
Pass a Target and a Port List to Start a Scan.
The target goes in the query string and the scan options in a JSON body. Only scan hosts you own or are authorized to test.
| Parameter | In | Type | Description | |
|---|---|---|---|---|
target | query | string | Required | A domain name or IP address to scan. |
timeout | query | integer | Optional | Scan timeout in seconds. Maximum and default 85. |
tcp_ | body | string | Optional | A list ("80,443"), a range ("440-445") or both. Leave it out to scan the default set for mode. |
udp_ | body | string | Optional | UDP ports to scan, in the same form. |
mode | body | string | Optional | light or full. Default light. |
version | body | boolean | Optional | Detect service versions. Default false. |
os | body | boolean | Optional | Detect the operating system. Default false. |
scripts | body | boolean | Optional | Run service detection scripts. Default false. |
Request
curl -X POST "https://api.deepinfo.com/v1/lookup/port-scan?target=deepinfo.com" \
-H "apikey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"tcp_ports": "80,443", "mode": "light", "version": true}'import requests
r = requests.post(
"https://api.deepinfo.com/v1/lookup/port-scan",
params={"target": "deepinfo.com"},
headers={"apikey": "YOUR_API_KEY"},
json={"tcp_ports": "80,443", "mode": "light", "version": True},
)
for p in r.json()["port_data"]["tcp"]:
print(p["port_number"], p["state"], p["service_name"])const r = await fetch(
'https://api.deepinfo.com/v1/lookup/port-scan?target=deepinfo.com',
{
method: 'POST',
headers: { apikey: 'YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ tcp_ports: '80,443', mode: 'light', version: true }),
}
)
const { status, port_data } = await r.json()
console.log(status, port_data.tcp)
Response
{
"status": "success",
"target": "deepinfo.com",
"target_ip": "104.26.11.21",
"port_data": {
"tcp": [
{
"port_number": 80,
"state": "open",
"service_name": "http",
"service_product": null,
"service_version": null,
"extra_data": {}
},
{
"port_number": 443,
"state": "open",
"service_name": "https",
"service_product": null,
"service_version": null,
"extra_data": {}
}
],
"udp": []
},
"os": [],
"check_date": "2026-09-22T16:06:23Z"
}
Scan what you own, or what you are authorized to test.
The API scans whatever target you pass, so the authorization has to come from you. The reference says so on the endpoint itself.
For your inventory there is a simpler route: External Attack Surface Management runs TCP and UDP scans on all approved assets, keeps each scan’s history and can notify your team when a new port opens.
What Each Field Tells You.
Each port carries one set of fields, so TCP and UDP results read alike.
| Field | Meaning |
|---|---|
status | success, or host_ when the host did not respond. |
target_ | The address the target resolved to, which is the address that was scanned. |
port_, port_ | One entry per port: port_, state, service_, service_, service_, extra_. |
os | Operating system matches, when os is true. |
check_ | When the scan ran, in UTC. |
service_ and service_ can stay null, as in this sample, when a service does not reveal them. Plan-dependent rate limits apply, one request per second by default.
When a Scan Can’t Wait.
Exposure Checks
Confirm that a port a scan flagged on one of your hosts is still open before you page its owner, or that it closed after the fix.
Vulnerability Triage
Read the product and version behind an open port on your host, then check them against CVE data.
Incident Scoping
See which services a host in your scope exposes right now, while the incident is still open.
Questions About Port Scan API
Can we scan a list of hosts?
Each request scans one target, so a list means one call per host within your rate limit. To cover an inventory you own, let Continuous Scanning run the scans instead.
How do we get the product and version behind each port?
Set version to true in the request body; it is off by default. With a product and version in hand, Vulnerability Search can filter CVEs on enrichment.cpe.vendor and enrichment.cpe.product.
What does an invalid request return?
A 400 when target is missing or the JSON body is invalid, with the rejected field named in parameters.
How is the Port Scan API priced?
As part of an API services plan, by volume and frequency. Like the other lookups, each request counts against your plan’s quota at one unit. See Data & API pricing.
Can analysts run a scan without writing code?
Yes. Instant Lookups runs Port Scan in the Deepinfo Platform. The same rule applies there: scan only hosts you own or are authorized to test.
Start With Your Hosts.
Scan a few of your own services to see the response shape, or let External Attack Surface Management scan the whole inventory for you. We can walk through both on a short call.