API Reference
Complete REST API documentation for IPCraft. Manage folders, subnets, IP addresses, VLANs, VRFs, locations, webhooks, and your team programmatically.
Base URL
All endpoint paths below are relative to this base URL. All resource IDs are UUIDs.
Authentication
All requests except the Network Tools endpoints require authentication via one of two methods:
- Session cookie — set by the magic-link and Google OAuth flows. HttpOnly, Secure, SameSite=Lax, 7-day sliding expiry.
- API key — pass an
Authorization: Bearer ipc_...header. Create keys in Settings or via the API Keys endpoints.
X-Requested-With: XMLHttpRequest header for CSRF protection. API key requests do not need this header.
API keys carry read and/or write permissions (both by default). Two additional restrictions apply to write requests:
- Free plan: API keys are read-only. POST/PATCH/DELETE requests with an API key return
403regardless of the key's permissions. - Viewer role: users with the viewer role cannot make write requests (
403).
curl https://api.ipcraft.io/api/v1/folders \
-H "Authorization: Bearer ipc_abc123..."
Example (Session cookie with CSRF)
curl -X POST https://api.ipcraft.io/api/v1/folders \
-H "Content-Type: application/json" \
-H "X-Requested-With: XMLHttpRequest" \
-b "ipcraft_session=..." \
-d '{"name": "Production"}'
Errors & Plan Limits
All errors return a JSON object with an error key and an appropriate HTTP status code.
{
"error": "subnet overlaps with existing subnet 10.0.0.0/16"
}
| Status | Meaning |
|---|---|
400 | Bad request — invalid input or validation error |
401 | Unauthorized — missing or invalid credentials |
402 | Payment required — plan limit exceeded |
403 | Forbidden — insufficient permissions, CSRF failure, or free-plan API write |
404 | Not found |
429 | Rate limited — too many requests |
Plan Limits
| Limit | Free | Pro ($29/mo) | Teams ($199/mo) | Enterprise |
|---|---|---|---|---|
| Users | 1 | 2 | 10 | Custom |
| Folders | 5 | Unlimited* | Unlimited* | Custom |
| Subnets | 100 | Unlimited* | Unlimited* | Custom |
| IP Addresses | 1,500 | 5,000 | 10,000 | Custom |
| VLANs | 10 | Unlimited* | Unlimited* | Custom |
| VRFs | 5 | Unlimited* | Unlimited* | Custom |
| Locations | 5 | Unlimited* | Unlimited* | Custom |
| Webhooks | — | 2 | 50 | 50 |
| API Keys | 5 | 100 | 100 | Custom |
| API Access | Read-only | Read/Write | Read/Write | Read/Write |
| Rate Limit (per user) | 10 req/s | 50 req/s | 50 req/s | Custom |
| Activity Log | 7 days | 30 days | 90 days | Custom |
* Unlimited features are subject to the fair use limits described in the Terms of Service.
Requests that would exceed your plan limits return 402. Authenticated requests are rate-limited per user based on your plan (enforced over a 1-minute window); responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.
Auth Endpoints
IPCraft is passwordless. Sign in with a magic link or Google OAuth — there are no register or password endpoints. Accounts and organizations are created automatically on first sign-in. Auth endpoints are rate-limited to 5 requests per minute per IP.
Send Magic Link
Send a passwordless sign-in link to the given email address. The link expires after 15 minutes. Limited to 3 links per email address per 15 minutes.
Request body{
"email": "john@example.com"
}
Response
{
"message": "sign-in link sent to john@example.com"
}
Verify Magic Link
Verify the magic link token from the email. This endpoint is opened by the browser, not called programmatically: on success it sets the ipcraft_session cookie and redirects (307) to the app. On first sign-in it creates the user and their organization. Invalid or expired tokens redirect to the login page with an error.
Google OAuth
Start the Google OAuth sign-in flow. Redirects to Google; the callback (/api/v1/auth/oauth/google/callback) sets the session cookie and redirects to the app. Browser-only — not for programmatic use.
Get Current User
Returns the authenticated user, their organization, and their role (admin, editor, or viewer). Requires auth.
{
"user": {
"id": "7f3e9a12-4b6c-4d2e-9f01-8a5b3c7d1e42",
"email": "john@example.com",
"name": "John Smith",
"email_verified": true,
"created_at": "2026-03-01T12:00:00Z"
},
"organization": {
"id": "c2a8f5d0-1e3b-4a7c-8d9e-0f1a2b3c4d5e",
"name": "John Smith's Org",
"slug": "john-smiths-org",
"plan": "free",
"created_at": "2026-03-01T12:00:00Z",
"updated_at": "2026-03-01T12:00:00Z"
},
"role": "admin"
}
Logout
Destroys the current session and clears the session cookie. No request body required.
Response200 OK
Delete Account
Permanently deletes the authenticated user's account and clears the session.
Response{
"message": "account deleted"
}
Folders
Folders are top-level organizational containers for grouping subnets (e.g., "Production", "Development").
List Folders
Returns all folders for the authenticated organization.
Response[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Production",
"description": "Production network ranges",
"sort_order": 0,
"created_at": "2026-03-01T12:00:00Z"
}
]
Create Folder
Create a new folder.
Request body{
"name": "Production",
"description": "Production network ranges",
"sort_order": 0
}
Only name is required. description and sort_order are optional.
Returns 201 with the created folder object.
Get Folder
Returns a single folder by ID.
Update Folder
Update a folder. All fields are optional — only provided fields are changed.
Request body{
"name": "Prod (US-East)",
"description": "US East production ranges",
"sort_order": 1
}
Response
200 OK
Delete Folder
Delete a folder. Subnets in the folder are kept and become unfoldered.
Response204 No Content
Subnets
Subnets represent CIDR network ranges. They form a hierarchy — creating a subnet within an existing range automatically nests it as a child. Overlap detection prevents conflicting ranges within the same VRF.
List Subnets
List all subnets, optionally filtered by folder. Includes utilization statistics and resolved VLAN/VRF/location/folder names. Not paginated.
Query parametersfolder_id— filter by folder (optional)
[
{
"id": "b4c5d6e7-f8a9-0123-bcde-f01234567890",
"folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"network": "10.0.0.0/16",
"name": "Core network",
"description": "Main production range",
"vlan_id": null,
"vrf_id": null,
"location_id": null,
"is_pool": false,
"gateway": "10.0.0.1",
"dns_primary": "10.0.0.53",
"dns_secondary": null,
"scan_enabled": false,
"tracked": true,
"utilization": 0.12,
"used_count": 7860,
"total_count": 65534,
"folder_name": "Production",
"created_at": "2026-03-01T12:00:00Z",
"updated_at": "2026-03-01T12:00:00Z"
}
]
Nullable/empty fields (parent_id, vlan_number, vrf_name, location_name, custom_fields, counts) are omitted when unset.
Create Subnet
Create a new subnet. The parent is auto-detected based on CIDR containment (and existing subnets inside the new range are re-parented under it). Partial overlaps within the same VRF are rejected with 400; parent/child containment is allowed.
{
"network": "10.0.1.0/24",
"name": "Web servers",
"description": "Web tier subnet",
"folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"vlan_id": null,
"vrf_id": null,
"location_id": null,
"gateway": "10.0.1.1",
"dns_primary": "10.0.0.53",
"dns_secondary": null,
"is_pool": false,
"tracked": true
}
Only network is required. All other fields are optional. tracked defaults to true when omitted; send false to create a structure-only container subnet that's excluded from utilization stats.
Returns 201 with the created subnet object. If the new subnet (created without a VRF) overlaps ranges that exist in other VRFs, the response is wrapped as {"subnet": {...}, "warnings": [{"id", "network", "name", "vrf_name"}]} — the create still succeeds.
Get Subnet
Returns a subnet with utilization statistics and its child subnets.
Response{
"id": "b4c5d6e7-f8a9-0123-bcde-f01234567890",
"network": "10.0.0.0/16",
"name": "Core network",
"utilization": 0.12,
"children": [
{
"id": "c5d6e7f8-a9b0-1234-cdef-012345678901",
"network": "10.0.1.0/24",
"name": "Web servers"
}
]
}
Update Subnet
Update subnet metadata. All fields are optional — only provided fields are changed. The network itself cannot be changed.
{
"name": "Web servers (prod)",
"description": "Production web tier",
"folder_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"location_id": null,
"vlan": "120",
"vrf": "CORP",
"is_pool": true,
"tracked": false,
"gateway": "10.0.1.1",
"dns_primary": "10.0.0.53",
"dns_secondary": null,
"custom_fields": { "rack": "R12" }
}
Note: unlike create, update takes vlan as a VLAN number (1–4094) and vrf as a VRF name; both are auto-created if they don't exist, and an empty string clears the assignment.
200 OK
Delete Subnet
Delete a subnet. Cascades to all child subnets and addresses.
204 No Content
Split Subnet
Split a subnet into equal parts. The number of parts must be a power of 2 (2, 4, 8, ... up to 1024). The new subnets inherit the original's folder, parent, name, VRF, and pool flag.
{
"parts": 4
}
Response
[
{ "id": "d6e7f8a9-...", "network": "10.0.0.0/26" },
{ "id": "e7f8a9b0-...", "network": "10.0.0.64/26" },
{ "id": "f8a9b0c1-...", "network": "10.0.0.128/26" },
{ "id": "a9b0c1d2-...", "network": "10.0.0.192/26" }
]
Subnet Usage
Returns utilization statistics for a subnet.
Response{
"subnet_id": "c5d6e7f8-a9b0-1234-cdef-012345678901",
"network": "10.0.1.0/24",
"used": 42,
"total": 254,
"utilization": 0.165
}
First Free IP
Returns the first available IP address in the subnet, or null if the subnet is full.
{
"ip": "10.0.1.5"
}
Response (full subnet)
{
"ip": null,
"message": "no available addresses"
}
Free Blocks
Finds unallocated child blocks of a requested size inside a subnet — the subnet-level counterpart of First Free IP. Returns the lowest free CIDR blocks of prefix length prefix that don't collide with any existing subnet in the same VRF (nested children are handled; supernets are ignored). prefix must be longer than the subnet's own prefix. limit caps the candidates returned (default 5, max 50); total is the count of all free blocks, and capped is true when the total hit the reporting cap of 1,000,000 (large IPv6 containers).
{
"subnet_id": "c5d6e7f8-a9b0-1234-cdef-012345678901",
"network": "10.0.0.0/16",
"prefix": 24,
"blocks": ["10.0.4.0/24", "10.0.5.0/24"],
"total": 253,
"capped": false
}
List Overlaps
Returns all pairs of subnets whose CIDR ranges overlap, classified by overlap type: duplicate (same CIDR in different VRFs), containment (parent/child), or partial.
[
{
"subnet_a": { "id": "...", "network": "10.0.0.0/16", "vrf_name": "CORP" },
"subnet_b": { "id": "...", "network": "10.0.0.0/16" },
"type": "duplicate"
}
]
Addresses
Individual IP address records within a subnet. Each address is validated against the parent subnet's CIDR range. Valid status values are assigned, reserved, d-dhcp (dynamic DHCP), m-dhcp (manual DHCP), and gateway.
List Addresses
List IP addresses in a subnet. Paginated: limit defaults to 1,000 (also the maximum); the total count is returned in the X-Total-Count response header.
[
{
"id": "0a1b2c3d-4e5f-6789-0abc-def123456789",
"subnet_id": "c5d6e7f8-a9b0-1234-cdef-012345678901",
"ip": "10.0.1.10",
"hostname": "web-01.prod",
"mac_address": "00:1a:2b:3c:4d:5e",
"description": "Primary web server",
"status": "assigned",
"owner": "platform-team",
"created_at": "2026-03-01T12:00:00Z",
"updated_at": "2026-03-01T12:00:00Z"
}
]
Optional fields (ptr_record, custom_fields, last_seen) are omitted when unset.
Create Address
Assign an IP address within a subnet. The IP must fall inside the subnet's CIDR range and not already be assigned.
Request body{
"ip": "10.0.1.10",
"hostname": "web-01.prod",
"mac_address": "00:1A:2B:3C:4D:5E",
"description": "Primary web server",
"status": "assigned",
"owner": "platform-team"
}
Only ip is required. status defaults to assigned.
Returns 201 with the created address object.
Batch Create
Assign up to 500 IPs in one request (e.g., reserve a range). status applies to all IPs and defaults to reserved.
{
"ips": ["10.0.1.20", "10.0.1.21", "10.0.1.22"],
"status": "reserved"
}
Response
{
"created": 3
}
Get Address
Returns a single address by ID (same shape as the list items above).
Update Address
Update address metadata. All fields are optional. The IP itself cannot be changed.
Request body{
"hostname": "web-01a.prod",
"mac_address": "00:1A:2B:3C:4D:5F",
"description": "Migrated web server",
"status": "assigned",
"owner": "platform-team",
"custom_fields": { "asset_tag": "A-1042" }
}
Response
200 OK
Delete Address
Remove an IP address assignment (release the IP).
Response204 No Content
Batch Update
Update the status and/or owner of up to 500 addresses at once.
Request body{
"ids": ["0a1b2c3d-...", "1b2c3d4e-..."],
"status": "reserved",
"owner": "network-team"
}
Response
{
"updated": 2
}
Batch Delete
Release up to 500 addresses at once.
Request body{
"ids": ["0a1b2c3d-...", "1b2c3d4e-..."]
}
Response
{
"deleted": 2
}
VLANs
Track VLAN assignments alongside your subnets. Standard CRUD:
A VLAN has a vlan_number (1–4094, required on create), optional name, description, and location_id. List responses include a computed subnet_count.
{
"id": "2c3d4e5f-6789-0abc-def1-234567890abc",
"vlan_number": 120,
"name": "Web tier",
"description": "Production web VLAN",
"subnet_count": 3,
"created_at": "2026-03-01T12:00:00Z"
}
VRFs
VRFs (virtual routing and forwarding instances) let the same CIDR exist more than once — overlap detection is scoped per VRF. Standard CRUD:
A VRF has a name (required on create), optional rd (route distinguisher, e.g. 65000:1) and description. List responses include a computed subnet_count.
{
"id": "3d4e5f67-890a-bcde-f123-4567890abcde",
"name": "CORP",
"rd": "65000:1",
"subnet_count": 12,
"created_at": "2026-03-01T12:00:00Z"
}
Locations
Physical sites (offices, datacenters) that subnets and VLANs can be tagged with. Standard CRUD:
A location has a name (required on create) and optional address. List responses include computed subnet_count and vlan_count.
{
"id": "4e5f6789-0abc-def1-2345-67890abcdef1",
"name": "Datacenter US-East",
"address": "Ashburn, VA",
"subnet_count": 8,
"vlan_count": 4,
"created_at": "2026-03-01T12:00:00Z"
}
Webhooks
Subscribe to real-time event notifications. See the Webhooks guide for setup instructions and signature verification.
List Webhooks
List all webhook subscriptions. The signing secret is never included in list responses.
Response[
{
"id": "5f678901-abcd-ef12-3456-7890abcdef12",
"url": "https://example.com/webhooks/ipcraft",
"description": "CMDB sync",
"event_types": ["subnet.created", "subnet.deleted"],
"is_active": true,
"failure_count": 0,
"created_at": "2026-03-21T16:00:00Z"
}
]
Create Webhook
Create a new webhook subscription. The URL must use HTTPS. Returns the signing secret — store it securely, it is only shown once.
Request body{
"url": "https://example.com/webhooks/ipcraft",
"description": "CMDB sync",
"event_types": ["subnet.created", "subnet.deleted"]
}
Leave event_types empty ([]) to receive all event types.
{
"id": "5f678901-abcd-ef12-3456-7890abcdef12",
"url": "https://example.com/webhooks/ipcraft",
"secret": "whsec_a1b2c3d4e5f6...",
"description": "CMDB sync",
"event_types": ["subnet.created", "subnet.deleted"],
"is_active": true
}
secret value immediately. It cannot be retrieved again. Use it to verify webhook signatures.Get Webhook
Get a single webhook subscription. The signing secret is not included.
Update Webhook
Update a webhook's URL, description, event types, or active status.
Request body{
"url": "https://new-endpoint.example.com/hook",
"event_types": ["address.created"],
"is_active": true
}
Response
200 OK
Delete Webhook
Permanently delete a webhook subscription and all its delivery history.
Response204 No Content
List Deliveries
List recent delivery attempts for a webhook. Supports ?limit= (default 50, max 100) and ?offset= query parameters. Delivery records are retained for 7 days.
[
{
"id": "6789012a-bcde-f123-4567-890abcdef123",
"event_type": "subnet.created",
"response_status": 200,
"duration_ms": 142,
"attempt": 1,
"delivered_at": "2026-03-21T16:30:00Z"
}
]
Test Ping
Send a test ping event to the webhook endpoint. Returns the delivery result so you can verify connectivity.
{
"event_type": "ping",
"response_status": 200,
"duration_ms": 95,
"attempt": 1
}
Returns 502 if the endpoint is unreachable or returns a non-2xx status.
Rotate Secret
Generate a new signing secret for the webhook. The old secret stops working immediately.
Response{
"secret": "whsec_new_secret_value..."
}
API Keys
Manage API keys for programmatic access. The full key is only shown once at creation time.
List Keys
List all API keys. Only the key prefix is shown — the full key is never returned after creation.
Response[
{
"id": "789012ab-cdef-1234-5678-90abcdef1234",
"name": "Ansible automation",
"key_prefix": "ipc_a1b2c3d4",
"permissions": ["read", "write"],
"created_at": "2026-03-01T12:00:00Z",
"last_used_at": "2026-03-14T09:15:00Z"
}
]
Create Key
Generate a new API key. The full key is only returned in this response — store it securely.
Request body{
"name": "Ansible automation",
"permissions": ["read", "write"]
}
permissions is optional and defaults to ["read", "write"]. Use ["read"] for a read-only key.
{
"id": "789012ab-cdef-1234-5678-90abcdef1234",
"name": "Ansible automation",
"key": "ipc_a1b2c3d4e5f6...(68 chars total)",
"key_prefix": "ipc_a1b2c3d4",
"permissions": ["read", "write"],
"created_at": "2026-03-01T12:00:00Z"
}
key value immediately. It cannot be retrieved again.Delete Key
Revoke an API key. Any requests using this key will immediately start returning 401.
204 No Content
Team
Manage organization members and invitations (Teams and Enterprise plans). Roles are admin, editor, and viewer.
List Members
[
{
"user_id": "7f3e9a12-4b6c-4d2e-9f01-8a5b3c7d1e42",
"email": "john@example.com",
"name": "John Smith",
"role": "admin",
"accepted_at": "2026-03-01T12:00:00Z"
}
]
Update Member Role
{
"role": "editor"
}
Response
{
"message": "role updated"
}
Remove Member
Remove a member from the organization.
Response{
"message": "member removed"
}
Invite User
Email an invitation to join your organization. Returns 402 if you're at your plan's seat limit. Invitation creation is limited to 10 per organization per hour. The invitee accepts via the emailed link (GET /api/v1/auth/accept-invite?token=..., browser-only).
{
"email": "teammate@example.com",
"role": "editor"
}
Response
Returns 201 with the invitation object (id, email, role, expires_at, created_at).
List Invitations
List pending invitations.
Cancel Invitation
{
"message": "invitation cancelled"
}
Billing
Manage your subscription plan via Stripe integration. Checkout, portal, and org-name endpoints require the admin role.
Get Plan
Returns current plan details, usage, and limits.
Response{
"plan": "free",
"org_name": "John Smith's Org",
"has_billing": false,
"usage": {
"folders": 1,
"subnets": 3,
"addresses": 42
},
"limits": {
"folders": 5,
"subnets": 100,
"addresses": 1500
}
}
Checkout
Creates a Stripe Checkout session for upgrading to Pro or Teams. Redirect the user to the returned URL. Returns 400 if the organization is already on a paid plan — use the Customer Portal to switch plans instead. For Enterprise, contact us.
{
"plan": "pro"
}
plan is "pro" or "teams". Omitting the body defaults to "pro".
{
"url": "https://checkout.stripe.com/c/pay/cs_live_..."
}
Customer Portal
Creates a Stripe Customer Portal session for managing billing, invoices, and cancellation.
Response{
"url": "https://billing.stripe.com/p/session/..."
}
Update Organization Name
Rename your organization (max 100 characters).
Request body{
"name": "Acme Networks"
}
Response
200 OK
Import & Export
Bulk import and CSV export. See the CSV Import & Export guide for the UI workflow, column aliases, and normalization rules. Import request bodies are limited to 10 MB.
Import Subnets
Create up to 1,000 subnets per request. Folders, VLANs, VRFs, and locations referenced by name/number are auto-created. Duplicates (same CIDR + VRF) and partial overlaps are skipped, not errored. Rows that would exceed plan limits are reported as errors; successfully imported rows are kept (no rollback).
Request body{
"subnets": [
{
"network": "10.0.1.0/24",
"name": "Web servers",
"folder": "Production",
"vlan": "120",
"vrf": "CORP",
"location": "Datacenter US-East",
"gateway": "10.0.1.1",
"is_pool": false
}
]
}
Only network is required per row. Also accepted: description, dns_primary, dns_secondary, scan_enabled, tracked (defaults to true when absent), custom_fields.
{
"results": [
{ "row": 1, "status": "created", "id": "...", "network": "10.0.1.0/24" }
],
"summary": { "created": 1, "skipped": 0, "errors": 0 }
}
Import Addresses
Create up to 1,000 addresses per request. Each row needs ip and subnet (the parent CIDR, which must already exist). Also accepted: hostname, mac_address, description, status, owner, ptr_record, custom_fields. Already-assigned IPs are skipped. Same response shape as subnet import.
{
"addresses": [
{
"ip": "10.0.1.10",
"subnet": "10.0.1.0/24",
"hostname": "web-01.prod",
"status": "assigned"
}
]
}
Export Subnets
Download all subnets as CSV (columns: network, name, description, folder, vlan, vrf, location, gateway, dns_primary, dns_secondary, is_pool, scan_enabled, tracked). Folder/VLAN/VRF/location are exported as human-readable names. folder_id optionally limits the export to one folder.
Export Addresses
Download addresses as CSV (columns: ip, subnet, hostname, mac_address, description, status, owner, ptr_record). subnet_id optionally limits the export to one subnet; omit it to export all addresses.
Search
Full-text search across subnets and addresses.
Search by IP address, hostname, network CIDR, name, or description. Returns matching subnets and addresses, up to 50 of each.
Query parametersq— search query (required, max 500 characters)
{
"subnets": [
{
"id": "c5d6e7f8-a9b0-1234-cdef-012345678901",
"network": "10.0.1.0/24",
"name": "Web servers"
}
],
"addresses": [
{
"id": "0a1b2c3d-4e5f-6789-0abc-def123456789",
"ip": "10.0.1.10",
"hostname": "web-01.prod"
}
]
}
Activity
Audit log of actions performed within your organization. History is retained per your plan (7/30/90 days; see Plan Limits).
Returns a paginated list of activity entries.
Query parameterslimit— entries to return (default 50, max 500)offset— pagination offsetaction,resource_type,user_id,since,until— optional filters
{
"entries": [
{
"id": 1042,
"user_id": "7f3e9a12-4b6c-4d2e-9f01-8a5b3c7d1e42",
"action": "create",
"resource_type": "subnet",
"resource_id": "c5d6e7f8-a9b0-1234-cdef-012345678901",
"changes": { "network": "10.0.1.0/24" },
"created_at": "2026-03-14T10:30:00Z"
}
],
"total": 137,
"users": { "7f3e9a12-...": "john@example.com" }
}
Activity Filters
Returns the distinct actions and resource_types present in your activity log, for building filter UIs.
Activity Export
Download the activity log as CSV (up to 10,000 rows). Accepts the same filter parameters as the list endpoint.
Network Tools
Public endpoints for common network lookups. No authentication required. Rate-limited per IP address: 10 requests per minute for lookups, and 3 requests per minute for active probes (ping, port scan, traceroute). Exceeding a limit returns 429 with a Retry-After header.
DNS Lookup
Resolve a domain against 3 independent resolvers: Cloudflare (1.1.1.1), Google (8.8.8.8), and Quad9 (9.9.9.9).
Query parametersdomain— domain name to resolve (required)type— record type, e.g. A, AAAA, MX, TXT, NS, CNAME, SOA (default: A)all=true— query all common record types at onceauthoritative=true— query the domain's own nameservers instead
{
"domain": "example.com",
"type": "A",
"results": [
{
"resolver": "1.1.1.1:53",
"records": ["93.184.216.34"],
"ttl": 300,
"response_time_ms": 2.3
},
{ "resolver": "8.8.8.8:53", "records": ["93.184.216.34"], "ttl": 300, "response_time_ms": 5.4 },
{ "resolver": "9.9.9.9:53", "records": ["93.184.216.34"], "ttl": 37, "response_time_ms": 0.7 }
]
}
DNS Propagation
Check how a DNS record has propagated across 8 resolvers around the world (Cloudflare, Google, Quad9, OpenDNS, Yandex, KT, Neustar, 114DNS). Each result includes the resolver's label and location in addition to the fields returned by DNS Lookup.
Reverse DNS
Perform a reverse DNS (PTR) lookup for an IP address, with forward-confirmation (FCrDNS) of each returned name.
Response{
"ip": "8.8.8.8",
"arpa_query": "8.8.8.8.in-addr.arpa.",
"names": [
{ "name": "dns.google", "fcrdns_valid": true }
],
"authoritative_ns": "ns1.google.com"
}
WHOIS Lookup
Perform a WHOIS lookup for a domain or IP address. Returns the raw WHOIS text plus a parsed summary: for domains, registrar, created, expires, expires_in_days, updated, nameservers, status; for IPs, cidr, net_name, organization, abuse_contact.
{
"query": "example.com",
"raw": "Domain Name: EXAMPLE.COM\n...",
"parsed": {
"registrar": "IANA",
"created": "1995-08-14T04:00:00Z",
"expires": "2026-08-13T04:00:00Z",
"expires_in_days": 40,
"nameservers": ["a.iana-servers.net", "b.iana-servers.net"]
}
}
SSL Certificate Check
Inspect a host's TLS certificate chain: each certificate's subject, issuer, sans, validity window, and days_remaining, plus chain_valid, tls_version, and cipher_suite.
{
"host": "example.com",
"tls_version": "TLS 1.3",
"cipher_suite": "TLS_AES_128_GCM_SHA256",
"chain_valid": true,
"certificates": [
{
"subject": "example.com",
"issuer": "DigiCert TLS RSA SHA256 2020 CA1",
"sans": ["example.com", "*.example.com"],
"not_after": "2026-08-29T21:41:26Z",
"days_remaining": 57,
"is_expired": false
}
]
}
SPF Check
Fetch and validate a domain's SPF record: parsed mechanisms, dns_lookup_count against the 10-lookup limit, plus valid, warnings, and errors.
{
"domain": "example.com",
"found": true,
"valid": true,
"raw": "v=spf1 include:_spf.example.com ~all",
"mechanisms": [
{ "qualifier": "+", "mechanism": "include", "value": "_spf.example.com" }
],
"dns_lookup_count": 1,
"dns_lookup_limit": 10,
"warnings": ["Using ~all (softfail) instead of -all (hardfail)"]
}
DMARC Check
Fetch and validate a domain's DMARC record: policy, subdomain_policy, parsed tags, plus valid, warnings, and errors.
{
"domain": "example.com",
"found": true,
"valid": true,
"policy": "reject",
"raw": "v=DMARC1; p=reject; rua=mailto:...",
"tags": { "v": "DMARC1", "p": "reject" }
}
Blacklist Check
Check an IP against 7 DNS blocklists (Spamhaus ZEN, Barracuda, SpamCop, Mailspike, UCEPROTECT L1, PSBL, SpamRATS).
Response{
"ip": "203.0.113.42",
"listed_count": 0,
"total_checked": 7,
"results": [
{ "list": "SpamCop", "zone": "bl.spamcop.net", "listed": false }
]
}
ASN Lookup
Look up the ASN, announcing prefix, and registry data for an IP address or AS number.
Response{
"query": "8.8.8.8",
"type": "ip",
"asn": "15169",
"as_name": "GOOGLE - Google LLC, US",
"prefix": "8.8.8.0/24",
"country": "US",
"rir": "arin",
"allocated": "2023-12-28"
}
HTTP/2 Check
Check which HTTP protocol versions a host supports.
Response{
"host": "example.com",
"http11": true,
"http2": true,
"http3_advertised": false,
"alpn_negotiated": "h2",
"tls_version": "TLS 1.3"
}
Ping (TCP Check)
TCP connectivity check to a host. Probes ports 80 and 443 by default; pass ?port= to check a specific port. Rate-limited to 3 requests per minute.
{
"host": "example.com",
"ip": "93.184.216.34",
"results": [
{ "port": 80, "open": true, "latency_ms": 1.3 },
{ "port": 443, "open": true, "latency_ms": 1.0 }
],
"checked_at": "2026-03-21T16:30:00Z"
}
Port Scan
Scan 19 common ports on a host (FTP, SSH, HTTP, HTTPS, DNS, SMTP, databases, RDP, etc.), or pass ?ports= with a comma-separated list (max 25). Rate-limited to 3 requests per minute.
{
"host": "example.com",
"open_count": 2,
"total": 19,
"results": [
{ "port": 80, "service": "HTTP", "category": "Web", "open": true, "latency_ms": 2.0 },
{ "port": 443, "service": "HTTPS", "category": "Web", "open": true, "latency_ms": 1.7 },
{ "port": 22, "service": "SSH", "category": "Remote Access", "open": false }
]
}
Traceroute
Trace the network path to a host with 3 round-trip measurements per hop. Unresponsive hops have null values. Rate-limited to 3 requests per minute.
{
"host": "example.com",
"ip": "93.184.216.34",
"hops": [
{ "hop": 1, "ip": "172.31.1.1", "rtt1_ms": 2.3, "rtt2_ms": 2.7, "rtt3_ms": 2.8 },
{ "hop": 2, "ip": null, "rtt1_ms": null, "rtt2_ms": null, "rtt3_ms": null }
]
}
My IP
Returns the client's public IP address, plus country, datacenter (edge location), and hostname (reverse DNS) when available.
{
"ip": "203.0.113.42",
"country": "US",
"datacenter": "DEN"
}
Request Headers
Returns the HTTP headers sent by the client. Pass ?url=https://... to instead fetch a remote site and get back its response headers with a security_checklist (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy).
{
"headers": {
"User-Agent": "curl/8.1.0",
"Accept": "*/*"
},
"method": "GET",
"proto": "HTTP/1.1"
}