# Trocar o admintoken

POST /admin/token/rotate

Gera um novo `admintoken` e invalida o atual na hora. Chame com o token atual no header `admintoken` e guarde o novo, que vem em `admin_token`.

- Uma troca a cada 24 horas; antes disso, `429` diz quando a próxima é permitida.
- Antes de responder, a api confirma o token novo com a Orkesio. Se não conseguir, desfaz a troca e responde `502`: o token atual continua valendo.
- Os tokens das inboxes não mudam.
- Em servidor de demonstração, a troca é bloqueada (`403`).

**Erro no formato v1.** Esta rota é a mesma do v1 (mesmo handler), então o erro sai no formato antigo, `{"error": "texto"}`, sem o código estável do `OrkesioError`. É a exceção ao padrão da Orkesio; trate pelo status HTTP.

## Autenticação

```json
[
  {
    "admintoken": []
  }
]
```

```json
{
  "admintoken": {
    "name": "admintoken",
    "type": "apiKey",
    "in": "header",
    "description": "Token de administrador para endpoints administrativos"
  }
}
```

## Respostas

```json
{
  "200": {
    "description": "Admin token rotacionado com sucesso",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "required": [
            "success",
            "message",
            "admin_token",
            "license_sync_triggered",
            "license_synced",
            "timestamp"
          ],
          "properties": {
            "success": {
              "type": "boolean",
              "example": true,
              "description": "Sempre `true`."
            },
            "message": {
              "type": "string",
              "example": "Admin token rotated successfully"
            },
            "admin_token": {
              "type": "string",
              "minLength": 50,
              "maxLength": 50,
              "pattern": "^[A-Za-z0-9]{50}$",
              "description": "O novo `admintoken`. Use-o no header `admintoken` daqui em diante.",
              "example": "AbC123Def456GhI789JkL012MnO345PqR678StU901VwX234Yz"
            },
            "license_sync_triggered": {
              "type": "boolean",
              "example": true,
              "description": "Sempre `true`: a api enviou o token novo para a Orkesio."
            },
            "license_synced": {
              "type": "boolean",
              "example": true,
              "description": "Sempre `true` no sucesso: a Orkesio confirmou o token novo (sem confirmação, a resposta é `502`)."
            },
            "timestamp": {
              "type": "integer",
              "format": "int64",
              "description": "Timestamp Unix em milissegundos.",
              "example": 1776892800000
            }
          }
        }
      }
    }
  },
  "401": {
    "description": "admintoken inválido ou ausente",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "error": {
              "type": "string",
              "example": "Unauthorized"
            }
          }
        }
      }
    }
  },
  "403": {
    "description": "Troca bloqueada em servidor de demonstração.",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "error": {
              "type": "string",
              "example": "Admin token rotation is disabled for free containers"
            }
          }
        }
      }
    }
  },
  "429": {
    "description": "Rotação bloqueada por cooldown de 24 horas",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "required": [
            "error",
            "last_rotated_at",
            "next_rotation_at",
            "retry_after_ms"
          ],
          "properties": {
            "error": {
              "type": "string",
              "example": "Admin token rotation cooldown active"
            },
            "last_rotated_at": {
              "type": "integer",
              "format": "int64",
              "description": "Timestamp Unix em milissegundos da última rotação concluída.",
              "example": 1776892800000
            },
            "next_rotation_at": {
              "type": "integer",
              "format": "int64",
              "description": "Timestamp Unix em milissegundos de quando uma nova rotação será permitida.",
              "example": 1776979200000
            },
            "retry_after_ms": {
              "type": "integer",
              "format": "int64",
              "description": "Tempo restante em milissegundos para liberar nova rotação.",
              "example": 86400000
            }
          }
        }
      }
    }
  },
  "500": {
    "description": "Erro interno ao rotacionar o token",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "error": {
              "type": "string",
              "example": "Failed to persist admin token"
            }
          }
        }
      }
    }
  },
  "502": {
    "description": "A api não conseguiu confirmar o token novo com a Orkesio e desfez a troca: o token atual continua valendo. Tente de novo.",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "required": [
            "success",
            "error",
            "license_synced",
            "timestamp"
          ],
          "properties": {
            "success": {
              "type": "boolean",
              "example": false
            },
            "error": {
              "type": "string",
              "example": "Failed to sync rotated admin token with license server"
            },
            "license_synced": {
              "type": "boolean",
              "example": false
            },
            "timestamp": {
              "type": "integer",
              "format": "int64",
              "example": 1776892800000,
              "description": "Unix em milissegundos."
            }
          }
        }
      }
    }
  }
}
```

**Estado:** Disponível

**Formato:** o mesmo da API v1 (caminho, campos e erros no padrão antigo).

## Compatibilidade de canais

| Canal | Compatível | Observação |
|---|---|---|
| WhatsApp (Web) | Sim |  |
| WhatsApp (API oficial) | Sim |  |
| Instagram | Sim |  |
| Messenger | Sim |  |
| Telegram | Sim |  |

## Eventos que esta rota gera

Nenhum. Esta rota não gera evento no webhook (nem em `GET /events`): o resultado vem só na resposta.

## Antes e depois (uazapi → Orkesio)

Na uazapi: `POST /admin/token/rotate`.

- Sem mudança: a mesma rota e o mesmo formato da uazapi.

## Guias relacionados

[Visão geral](/docs/overview) · [O que funciona em cada canal](/docs/canais) · [O que muda da uazapi](/docs/o-que-muda)
