Bitping Developer API
Not signed up yet? Get started for as little as $5/month
This documentation covers the various job types available through the Customer Jobs API. Each job type allows you to perform specific network tests from different locations and ISPs.
OpenAPI Documentation
For a comprehensive and interactive view of our API, please refer to our OpenAPI specification:
Bitping API OpenAPI Specification
For the best experience, we recommend viewing the specification in an OpenAPI viewer such as Swagger UI or ReDoc. You can also import the URL into Yaak, Postman, Insomnia or your favourite desktop API client.
DNS Lookup
Perform a DNS lookup for specified hostnames.
Endpoint
POST /jobs/customer/dns
Request Body
| Field | Type | Description |
|---|---|---|
| hostnames | string[] | Array of hostnames to lookup |
| countryCode | string (optional) | Filter nodes by country code |
| ispRegex | string (optional) | Filter nodes by ISP regex |
| residential | string (optional) | Filter by residential nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| proxy | string (optional) | Filter by proxy nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| mobile | string (optional) | Filter by mobile nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| configuration | object (optional) | DNS-specific configuration |
Configuration Object
| Field | Type | Description |
|---|---|---|
| dnsServers | string[] (optional) | List of DNS servers to use (e.g. ‘8.8.8.8:53’, ‘1.1.1.1:53’) |
| lookupTypes | string[] (optional) | Types of DNS lookups to perform (e.g., “MX”, “NS”, “IP”, “TXT”, “SOA”, “SRV”, “TLSA”) |
Response
Returns the DNS lookup results along with node information.
{
nodeInfo: {
operatingSystem: string;
isp: string;
mobile: boolean;
proxy: boolean;
regionName: string;
countryCode: string;
lat: number;
lon: number;
};
results: Array<{
endpoint: string;
duration: number;
error?: string;
result?: {
mx: string[];
ns: string[];
ips: string[];
txt: string[];
soa: string[];
srv: string[];
tlsa: string[];
dnsServers: string[];
};
}>;
}
HTTP Request
Perform an HTTP request to specified hostnames.
Endpoint
POST /jobs/customer/http/{method}
Parameters
| Parameter | Description |
|---|---|
| method | The HTTP method to use (e.g., GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD) |
Request Body
| Field | Type | Description |
|---|---|---|
| hostnames | string[] | Array of hostnames to lookup |
| countryCode | string (optional) | Filter nodes by country code |
| ispRegex | string (optional) | Filter nodes by ISP regex |
| residential | string (optional) | Filter by residential nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| proxy | string (optional) | Filter by proxy nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| mobile | string (optional) | Filter by mobile nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| configuration | object (optional) | DNS-specific configuration |
Configuration Object
| Field | Type | Description |
|---|---|---|
| headers | object (optional) | Key-value pairs of HTTP headers |
| regex | string (optional) | Regex pattern to match in the response |
| statusCodes | number[] (optional) | Expected status codes |
| body | string (optional) | Request body for POST, PUT, PATCH requests |
| returnBody | boolean (optional) | Whether to return the response body |
| transport | ”TCP” | “AUTO” | “QUIC” (optional) | Transport preference. TCP = HTTP/2 or HTTP/1.1 (default); AUTO = try HTTP/3, fall back to TCP (populates fallbackChain); QUIC = HTTP/3 only, fails if the target doesn’t support it |
| sslInfo | boolean (optional) | Capture full TLS certificate info. Adds a separate TCP+TLS handshake (~30 ms; not counted toward reported latency) |
Response
Returns the HTTP response along with node information.
{
nodeInfo: {
operatingSystem: string;
isp: string;
mobile: boolean;
proxy: boolean;
regionName: string;
countryCode: string;
lat: number;
lon: number;
};
results: Array<{
endpoint: string;
duration: number;
error?: string;
result?: {
statusCode: number;
bodyHash: string;
matches: string[];
headers: Record<string, string>;
body?: string;
// Per-phase RELATIVE timings: each field is that phase's own elapsed
// time (not cumulative-from-start), so the phases sum to the total.
metrics?: {
dnsResolveDurationMs?: number; // DNS resolution (unset for IP-literal targets)
tcpConnectDurationMs?: number; // TCP connect (unset on HTTP/3 — no TCP)
tlsHandshakeDurationMs?: number; // TLS handshake (unset for http:// and HTTP/3)
quicHandshakeDurationMs?: number; // QUIC handshake — HTTP/3 only
connectionReadyDurationMs: number; // protocol preface/SETTINGS after transport/TLS
httpTtfbDurationMs: number; // wait: connection-ready → first response byte
contentDownloadDurationMs: number; // first response byte → last byte
};
// Full TLS certificate info. Present only when configuration.sslInfo = true.
sslInfo?: {
isValid: boolean;
issuer: string;
subject: string;
subjectAlternativeNames: string[];
notBefore: string;
notAfter: string;
serialNumber: string;
signatureAlgorithm: string;
version: number;
};
negotiatedProtocol?: string; // ALPN result: "h2" | "http/1.1" | "http/1.0" | "h3"
addressFamilyUsed?: string; // happy-eyeballs winner: "ipv4" | "ipv6"
// Protocols attempted before the negotiated one succeeded. Empty unless a
// transport fallback occurred (e.g. transport: "AUTO" and HTTP/3 failed).
fallbackChain: Array<{
protocol: string; // "h3" | "h2" | "http/1.1" | "http/1.0"
error: string; // rendered error for this attempt
advertisedByServer?: boolean; // did the server advertise this protocol (e.g. via Alt-Svc)?
errorCode: string; // machine-readable code, e.g. "ERROR_CODE_HTTP_QUIC_HANDSHAKE_FAILED"
}>;
// Cookies observed during the probe, including on redirect hops. Values
// are intentionally omitted — metadata only.
observedCookies: Array<{
name: string;
domain: string;
path: string;
secure: boolean;
}>;
redirectsFollowed: number; // HTTP redirects followed to reach the final response
finalUrl?: string; // final URL after redirects + normalisation
};
}>;
}
ICMP Ping
Perform a ping test to specified hostnames.
Endpoint
POST /jobs/customer/ping/icmp
Request Body
| Field | Type | Description |
|---|---|---|
| hostnames | string[] | Array of hostnames to lookup |
| countryCode | string (optional) | Filter nodes by country code |
| ispRegex | string (optional) | Filter nodes by ISP regex |
| residential | string (optional) | Filter by residential nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| proxy | string (optional) | Filter by proxy nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| mobile | string (optional) | Filter by mobile nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| configuration | object (optional) | DNS-specific configuration |
Configuration Object
| Field | Type | Description |
|---|---|---|
| attempts | number (optional) | Number of ping attempts |
| payloadSize | number (optional) | Size of the ping payload |
| timeoutMillis | number (optional) | Timeout in milliseconds |
Response
Returns the ping results along with node information.
{
nodeInfo: {
operatingSystem: string;
isp: string;
mobile: boolean;
proxy: boolean;
regionName: string;
countryCode: string;
lat: number;
lon: number;
};
results: Array<{
endpoint: string;
duration: number;
error?: string;
result?: {
avg: number;
max: number;
min: number;
stdDev: number;
ipAddress: string;
packetLoss: number;
packetsRecv: number;
packetsSent: number;
trips: number;
attempts: number;
};
}>;
}
HLS Stream Test
Perform an HLS (HTTP Live Streaming) test on specified stream URLs.
Endpoint
POST /jobs/customer/hls
Request Body
| Field | Type | Description |
|---|---|---|
| hostnames | string[] | Array of hostnames to lookup |
| countryCode | string (optional) | Filter nodes by country code |
| ispRegex | string (optional) | Filter nodes by ISP regex |
| residential | string (optional) | Filter by residential nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| proxy | string (optional) | Filter by proxy nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| mobile | string (optional) | Filter by mobile nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| configuration | object (optional) | DNS-specific configuration |
Configuration Object
| Field | Type | Description |
|---|---|---|
| headers | object (optional) | Key-value pairs of HTTP headers |
| transport | ”TCP” | “AUTO” | “QUIC” (optional) | Transport preference for the manifest and segment fetches. TCP (default), AUTO (try HTTP/3 then fall back), or QUIC (HTTP/3 only) |
| sampleMaxBytes | number (optional) | Max bytes to download per content-segment sample. Clamped server-side (64 MiB ceiling). Defaults to 16 MiB |
| sampleMaxDurationSecs | number (optional) | Max wall-clock seconds per content-segment sample. Clamped server-side (30s). Defaults to 10s |
Response
Returns the HLS stream test results along with node information.
The HLS response reuses two shared shapes. PerformanceMetrics holds per-phase
RELATIVE timings (each field is that phase’s own elapsed time, not
cumulative-from-start, so the phases sum to the total):
type PerformanceMetrics = {
dnsResolveDurationMs?: number; // DNS resolution (unset for IP-literal targets)
tcpConnectDurationMs?: number; // TCP connect (unset on HTTP/3 — no TCP)
tlsHandshakeDurationMs?: number; // TLS handshake (unset for http:// and HTTP/3)
quicHandshakeDurationMs?: number; // QUIC handshake — HTTP/3 only
connectionReadyDurationMs: number; // protocol preface/SETTINGS after transport/TLS
httpTtfbDurationMs: number; // wait: connection-ready → first response byte
contentDownloadDurationMs: number; // first response byte → last byte
};
type DownloadMetrics = {
size: number;
timeMs: number;
bytesPerSecond: number;
};
// A rendition (media) playlist and its sampled content segments.
type Rendition = {
file: string;
downloadMetrics?: DownloadMetrics;
metrics?: PerformanceMetrics;
contentFragmentMetrics: Array<{
file: string;
contentFragmentDurationSecs: number;
metrics?: PerformanceMetrics;
downloadMetrics?: DownloadMetrics;
downloadRatio: number;
responseHeaders?: Record<string, string>; // raw segment-fetch headers
negotiatedProtocol?: string; // "h2" | "http/1.1" | "http/1.0" | "h3"
addressFamilyUsed?: string; // "ipv4" | "ipv6"
}>;
targetDurationSecs: number;
discontinuitySequence: number;
resolution: string;
bandwidth: number;
responseHeaders?: Record<string, string>; // raw rendition-manifest headers
negotiatedProtocol?: string;
addressFamilyUsed?: string;
};
{
nodeInfo: {
operatingSystem: string;
isp: string;
mobile: boolean;
proxy: boolean;
regionName: string;
countryCode: string;
lat: number;
lon: number;
};
results: Array<{
endpoint: string;
duration: number;
error?: string;
// Either `master` or `rendition` is present, depending on whether the
// target URL was a master playlist or a media (rendition) playlist.
result?: {
master?: {
file: string;
downloadMetrics?: DownloadMetrics;
metrics?: PerformanceMetrics;
renditions: Rendition[];
responseHeaders?: Record<string, string>; // raw master-manifest headers (cf-ray, x-cache, …)
negotiatedProtocol?: string; // "h2" | "http/1.1" | "http/1.0" | "h3"
addressFamilyUsed?: string; // "ipv4" | "ipv6"
};
rendition?: Rendition;
};
}>;
}
Traceroute
Trace the network path to a destination hop-by-hop, measuring per-hop latency and packet loss. Supports ICMP, UDP, and TCP probes with three multipath strategies (CLASSIC, PARIS, DUBLIN).
Endpoint
POST /jobs/customer/traceroute
Request Body
| Field | Type | Description |
|---|---|---|
| hostnames | string[] | Array of hostnames or IPs to trace |
| countryCode | string (optional) | Filter nodes by country code |
| ispRegex | string (optional) | Filter nodes by ISP regex |
| residential | string (optional) | Filter by residential nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| proxy | string (optional) | Filter by proxy nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| mobile | string (optional) | Filter by mobile nodes: “ALLOWED”, “DENIED”, or “REQUIRED” |
| configuration | object (optional) | Traceroute-specific configuration |
Configuration Object
| Field | Type | Description |
|---|---|---|
| protocol | ”ICMP” | “UDP” | “TCP” (optional) | Probe protocol. Defaults to ICMP |
| multipathStrategy | ”CLASSIC” | “PARIS” | “DUBLIN” (optional) | Multipath strategy. PARIS and DUBLIN require privileged mode + UDP. Defaults to CLASSIC |
| maxHops | number (optional) | Maximum hops to probe (1–255) |
| firstTtl | number (optional) | TTL of the first probe (1–255) |
| queriesPerHop | number (optional) | Number of probes per hop |
| timeoutMs | number (optional) | Per-probe timeout in milliseconds |
| packetSize | number (optional) | Probe packet size in bytes |
| port | number (optional) | Destination port for UDP/TCP probes (1–65535) |
| resolveHostnames | boolean (optional) | Reverse-DNS each hop’s IP |
| disableIpv6Upgrade | boolean (optional) | Skip the DNS64/NAT64 IPv6 fallback used on IPv4-only mobile carriers |
Response
Returns the traceroute results along with node information.
{
nodeInfo: {
operatingSystem: string;
isp: string;
mobile: boolean;
proxy: boolean;
regionName: string;
countryCode: string;
lat: number;
lon: number;
};
results: Array<{
endpoint: string;
duration: number;
error?: string;
result?: {
protocol: "ICMP" | "UDP" | "TCP";
multipathStrategy: "CLASSIC" | "PARIS" | "DUBLIN";
targetIp: string;
reached: boolean;
hops: Array<{
ttl: number;
ipAddress?: string;
hostname?: string;
sent: number;
received: number;
packetLoss: number;
avgMs?: number;
minMs?: number;
maxMs?: number;
stdDevMs?: number;
}>;
};
}>;
}