---
title: "Rotate the egress IP"
method: POST
path: "/v1/ports/{id}/rotate"
tags: ["ports"]
---

# Rotate the egress IP

`POST /v1/ports/{id}/rotate`

## Request

- Base URL: `https://api.portproof.org`
- URL: `https://api.portproof.org/v1/ports/{id}/rotate`
- Auth: HTTP bearer

Rotates the port and waits for the Ed25519-signed rotation record (default `wait=true`). Own-farm ports wait up to 180 s; partner-network ports up to 30 s, because their IP change takes about a minute. On timeout, or with `wait=false`, the answer is 202 with `rotation_id`: poll `GET /v1/ports/{id}/rotation/{rotation_id}` for the record. Rate limit: 1 per 60 s per port, taken before the rotation starts (429 `port_cooldown` with `retry_after`). Requires an `Idempotency-Key` header (CONTRACT §1): the same key with the same body within 24 h replays the stored response; a different body returns 409 `idempotency_conflict`.

## Path parameters

- `id` string, required

## Request body

- object
  - `wait` boolean

## Response `200`

Default Response

- object
  - `id` string, required
  - `port_id` string, required
  - `site_code` string, required
  - `requested_by` 'manual' | 'api' | 'token' | 'schedule' | 'health' | 'migration', required
  - `old_ip4` string, nullable, required
  - `new_ip4` string, nullable, required
  - `old_ip6_prefix` string, nullable, required
  - `new_ip6_prefix` string, nullable, required
  - `v4_is_nat64` boolean, required
  - `rotated` boolean, required
  - `attempts` integer, required
  - `elapsed_ms` integer, required
  - `reason` 'ok' | 'carrier_sticky' | 'attach_timeout' | 'driver_error' | 'cooldown', required
  - `driver` string, required
  - `carrier` string, required
  - `mcc_mnc` string, required
  - `asn` string, nullable, required
  - `geo` object, required
    - `country` string, nullable, required
    - `region` string, nullable, required
    - `sources` integer, required
  - `reputation` object, nullable, required
    - `flagged` boolean, required
    - `hosting` boolean, required
    - `scored_at` string, date-time, nullable, required
  - `sticky_window_s` integer, required
  - `ip_shared_with_own_ports` integer, required
  - `sim_contract_class` 'prepaid' | 'business' | 'm2m', required
  - `signed_at` string, date-time, required
  - `key_id` string, required
  - `attestation` 'signed' | 'observed'
  - `sig` string, required

## Other responses

- `202`: Default Response
- `404`: Default Response
- `409`: Default Response
- `429`: Default Response

---

[API](https://skmtc.dev/portproof/apis/portproof-api.md) · [All operations](https://skmtc.dev/portproof/apis/portproof-api/llms.txt) · [OpenAPI document](https://skmtc.dev/portproof/apis/portproof-api/revisions/4143916c0fac?raw)
