IPTunnel Documentation
Back Home
Operations

API Reference

All public and activation-lifecycle routes with request and response examples.

Health check

GET /api/v2/healthz

Response 200

{
  "data": { "status": "ok" },
  "meta": { "message": "OK" }
}

Issue install code

POST /api/v2/slowdns/code/issue

No request body is required, but the caller must first load GET /slowdns so the browser receives the slowdns_browser session cookie. The endpoint is rate limited at 3 per IP per hour, 10 per IP per day, with extra per-session and per-fingerprint caps.

Response 201

{
  "data": {
    "install_code": "IPT-SD-XXXXXX-XXXXXX-XXXXXX",
    "expires_at": "2026-03-31T12:05:00+00:00",
    "ttl_seconds": 300
  },
  "meta": { "message": "SlowDNS install code issued" }
}

Response 403 — browser session missing or expired

{ "error": { "code": "browser_session_required", "message": "Open the SlowDNS page first before requesting an install code." } }

Response 429 — rate limit exceeded

{ "error": { "code": "rate_limit_exceeded", "message": "Too many requests. Please wait before trying again." } }

Precheck install code

POST /api/v2/slowdns/install/precheck

Called by the installer immediately after the code is entered. This validates the code and machine identity before hostname, tunnel domain, or public IP are collected.

Request body

{
  "install_code": "IPT-SD-XXXXXX-XXXXXX-XXXXXX",
  "machine_id": "</etc/machine-id contents>",
  "ssh_fingerprint": "SHA256:...",
  "product": "slowdns",
  "installer_version": "2026.03.31"
}

Response 200

{
  "data": {
    "install_code": "IPT-SD-XXXXXX-XXXXXX-XXXXXX",
    "install_code_hint": "IPT-SD-XXXX...XXXXXX",
    "precheck_token": "eyJhbGciOiJIUzI1NiJ9...",
    "precheck_expires_at": "2026-03-31T12:15:00+00:00",
    "machine_binding": {
      "machine_id": "...",
      "ssh_fingerprint": "SHA256:..."
    }
  },
  "meta": { "message": "Install code validated" }
}

Activate install code

POST /api/v2/slowdns/install/activate

Rate limited to 5 requests per IP per 24 hours and 5 requests per machine per 24 hours. Called by the installer only after the operator confirms the final hostname and public IP.

Request body

{
  "install_code": "IPT-SD-XXXXXX-XXXXXX-XXXXXX",
  "precheck_token": "eyJhbGciOiJIUzI1NiJ9...",
  "hostname": "ns1.example.com",
  "public_ip": "1.2.3.4",
  "machine_id": "</etc/machine-id contents>",
  "ssh_fingerprint": "SHA256:...",
  "requested_ref": "main",
  "installer_version": "2026.03.30"
}

Response 200

{
  "data": {
    "activation_id": "act_a1b2c3d4e5f6a7b8",
    "install_token": "eyJhbGciOiJIUzI1NiJ9...",
    "install_token_expires_at": "2026-03-31T12:15:00+00:00",
    "install_code": "IPT-SD-XXXXXX-XXXXXX-XXXXXX",
    "machine_binding": {
      "hostname": "ns1.example.com",
      "public_ip": "1.2.3.4",
      "machine_id": "...",
      "ssh_fingerprint": "SHA256:..."
    }
  },
  "meta": { "message": "Install token issued" }
}

Confirm install

POST /api/v2/slowdns/install/confirm

Called by the installer after all services are confirmed active. Permanently consumes the install token.

Request body

{
  "activation_id": "act_a1b2c3d4e5f6a7b8",
  "install_token": "eyJhbGciOiJIUzI1NiJ9..."
}

Response 200

{
  "data": { "activation_id": "act_a1b2c3d4e5f6a7b8", "status": "confirmed" },
  "meta": { "message": "Install confirmed" }
}

Release / rollback

POST /api/v2/slowdns/install/release

Called automatically by the installer's EXIT trap when the install fails before confirmation. If the install token has not been used and has not expired, the install code is restored to issued so the operator can retry.

Request body

{
  "activation_id": "act_a1b2c3d4e5f6a7b8"
}

Response 200

{
  "data": {
    "activation_id": "act_a1b2c3d4e5f6a7b8",
    "status": "released",
    "install_code_restored": true
  },
  "meta": { "message": "Activation released" }
}

Error response format

All v2 error responses use the same envelope:

{
  "error": {
    "code": "install_code_expired",
    "message": "Install code has expired."
  }
}

The code field is a machine-readable string. The message field is human-readable and safe to display to operators.

Main stack routes

POST /register
POST /checkin
POST /revoke
GET  /status

Legacy-compatible routes used by the IPTunnel installer and server agents for registration, periodic check-ins, and server revocation.