Files
ipam/openapi.json
T
jamie 7118f917b8
Release / Build & Release (pull_request) Successful in 30s
Release / SonarQube (pull_request) Successful in 25s
feat: add OpenAPI and Swagger UI endpoints for API documentation
2026-07-21 11:12:11 +01:00

2641 lines
58 KiB
JSON

{
"openapi": "3.0.3",
"info": {
"title": "IPAM API",
"version": "2.0",
"description": "JSON REST API for IP Address Management (IPAM).\n\n**Authentication**\n- Browser UI: session cookie after `POST /auth/login` (send cookies on subsequent requests).\n- Automation: API key via `X-API-Key` header, `Authorization: Bearer <key>`, or `?api_key=` query parameter.\n Regenerate keys from the Users page in the web UI.\n\n**Authorization**\nEach endpoint requires a permission (see `x-permission`). API keys inherit permissions from the user's role.\n\n**List responses**\nMost list endpoints return `{ \"items\": [...] }`. Audit log returns `{ \"items\", \"total\" }`."
},
"servers": [
{
"url": "/api/v2",
"description": "API v2 base path"
}
],
"tags": [
{
"name": "Authentication"
},
{
"name": "Account"
},
{
"name": "Info"
},
{
"name": "Dashboard"
},
{
"name": "Search"
},
{
"name": "Devices"
},
{
"name": "Subnets"
},
{
"name": "IP Addresses"
},
{
"name": "Tags"
},
{
"name": "Racks"
},
{
"name": "Custom Fields"
},
{
"name": "DHCP"
},
{
"name": "Audit"
},
{
"name": "Users"
},
{
"name": "Roles"
},
{
"name": "Permissions"
},
{
"name": "Settings"
},
{
"name": "Bulk"
}
],
"components": {
"securitySchemes": {
"ApiKeyHeader": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key"
},
"BearerAuth": {
"type": "http",
"scheme": "bearer",
"description": "API key as Bearer token"
},
"ApiKeyQuery": {
"type": "apiKey",
"in": "query",
"name": "api_key"
},
"SessionCookie": {
"type": "apiKey",
"in": "cookie",
"name": "session",
"description": "Flask session cookie after login (browser only)"
}
},
"schemas": {
"Error": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"permission": {
"type": "string",
"description": "Required permission when 403"
}
}
},
"OkResponse": {
"type": "object",
"properties": {
"ok": {
"type": "boolean"
}
}
},
"ItemsResponse": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {}
}
}
},
"LoginRequest": {
"type": "object",
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string",
"format": "password"
}
}
},
"Verify2faRequest": {
"type": "object",
"required": [
"code"
],
"properties": {
"code": {
"type": "string"
},
"use_backup": {
"type": "boolean",
"default": false
}
}
},
"Setup2faRequest": {
"type": "object",
"required": [
"action"
],
"properties": {
"action": {
"type": "string",
"enum": [
"generate",
"verify"
]
},
"code": {
"type": "string",
"description": "Required when action is verify"
}
}
},
"ChangePasswordRequest": {
"type": "object",
"required": [
"current_password",
"new_password"
],
"properties": {
"current_password": {
"type": "string"
},
"new_password": {
"type": "string"
}
}
},
"PasswordConfirmRequest": {
"type": "object",
"required": [
"password"
],
"properties": {
"password": {
"type": "string"
}
}
},
"DeviceCreate": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
}
}
},
"DeviceUpdate": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
}
}
},
"AssignIpRequest": {
"type": "object",
"required": [
"ip_id"
],
"properties": {
"ip_id": {
"type": "integer"
}
}
},
"SubnetCreate": {
"type": "object",
"required": [
"name",
"cidr"
],
"properties": {
"name": {
"type": "string"
},
"cidr": {
"type": "string",
"example": "10.0.0.0/24"
},
"site": {
"type": "string"
},
"vlan_id": {
"type": "integer",
"nullable": true
},
"vlan_description": {
"type": "string"
},
"vlan_notes": {
"type": "string"
}
}
},
"SubnetUpdate": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"cidr": {
"type": "string"
},
"site": {
"type": "string"
},
"vlan_id": {
"type": "integer",
"nullable": true
},
"vlan_description": {
"type": "string"
},
"vlan_notes": {
"type": "string"
}
}
},
"RackCreate": {
"type": "object",
"required": [
"name",
"site",
"height_u"
],
"properties": {
"name": {
"type": "string"
},
"site": {
"type": "string"
},
"height_u": {
"type": "integer",
"minimum": 1
}
}
},
"RackUpdate": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"site": {
"type": "string"
},
"height_u": {
"type": "integer",
"minimum": 1
}
}
},
"RackDeviceCreate": {
"type": "object",
"required": [
"position_u",
"side"
],
"properties": {
"position_u": {
"type": "integer",
"minimum": 1
},
"side": {
"type": "string",
"enum": [
"front",
"back"
]
},
"device_id": {
"type": "integer",
"description": "Networked device (mutually exclusive with nonnet_device_name)"
},
"nonnet_device_name": {
"type": "string",
"description": "Label for non-networked equipment"
}
}
},
"CustomFieldCreate": {
"type": "object",
"required": [
"entity_type",
"name",
"field_key",
"field_type"
],
"properties": {
"entity_type": {
"type": "string",
"enum": [
"device",
"subnet"
]
},
"name": {
"type": "string"
},
"field_key": {
"type": "string"
},
"field_type": {
"type": "string",
"enum": [
"text",
"textarea",
"number",
"select",
"checkbox",
"date"
]
},
"required": {
"type": "boolean",
"default": false
},
"default_value": {
"type": "string",
"nullable": true
},
"help_text": {
"type": "string",
"nullable": true
},
"display_order": {
"type": "integer",
"default": 0
},
"validation_rules": {
"type": "object",
"additionalProperties": true
}
}
},
"CustomFieldUpdate": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"field_type": {
"type": "string",
"enum": [
"text",
"textarea",
"number",
"select",
"checkbox",
"date"
]
},
"required": {
"type": "boolean"
},
"default_value": {
"type": "string",
"nullable": true
},
"help_text": {
"type": "string",
"nullable": true
},
"display_order": {
"type": "integer"
},
"validation_rules": {
"type": "object",
"additionalProperties": true
}
}
},
"CustomFieldsPatch": {
"type": "object",
"properties": {
"custom_fields": {
"type": "object",
"additionalProperties": true
}
}
},
"CustomFieldReorder": {
"type": "object",
"required": [
"entity_type",
"field_orders"
],
"properties": {
"entity_type": {
"type": "string",
"enum": [
"device",
"subnet"
]
},
"field_orders": {
"type": "object",
"additionalProperties": {
"type": "integer"
},
"description": "Map of field definition ID to display order"
}
}
},
"DhcpConfigure": {
"type": "object",
"properties": {
"remove": {
"type": "boolean",
"description": "If true, remove the DHCP pool for this subnet"
},
"pools": {
"type": "array",
"items": {
"type": "object",
"required": [
"start_ip",
"end_ip"
],
"properties": {
"start_ip": {
"type": "string"
},
"end_ip": {
"type": "string"
},
"excluded_ips": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
},
"TagCreate": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"color": {
"type": "string",
"default": "#6B7280"
},
"description": {
"type": "string"
}
}
},
"TagUpdate": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"color": {
"type": "string"
},
"description": {
"type": "string"
}
}
},
"AssignTagRequest": {
"type": "object",
"required": [
"tag_id"
],
"properties": {
"tag_id": {
"type": "integer"
}
}
},
"IpNotesPatch": {
"type": "object",
"required": [
"notes"
],
"properties": {
"notes": {
"type": "string",
"nullable": true
}
}
},
"UserCreate": {
"type": "object",
"required": [
"name",
"email",
"password"
],
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string"
},
"role_id": {
"type": "integer"
}
}
},
"UserUpdate": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string"
},
"role_id": {
"type": "integer"
}
}
},
"RoleCreate": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"require_2fa": {
"type": "boolean",
"default": false
},
"permission_ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"RoleUpdate": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"require_2fa": {
"type": "boolean"
},
"permission_ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"SettingsUpdate": {
"type": "object",
"properties": {
"org_name": {
"type": "string"
},
"org_logo": {
"type": "string",
"description": "URL or path to PNG logo"
},
"accent_color": {
"type": "string",
"example": "#1ebe8a"
}
}
},
"BulkAssignIps": {
"type": "object",
"required": [
"device_id",
"ip_ids"
],
"properties": {
"device_id": {
"type": "integer"
},
"ip_ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"BulkCreateDevices": {
"type": "object",
"required": [
"names"
],
"properties": {
"names": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"BulkAssignTags": {
"type": "object",
"required": [
"device_ids",
"tag_id"
],
"properties": {
"device_ids": {
"type": "array",
"items": {
"type": "integer"
}
},
"tag_id": {
"type": "integer"
}
}
},
"BulkExportSubnets": {
"type": "object",
"required": [
"subnet_ids"
],
"properties": {
"subnet_ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
}
},
"parameters": {
"deviceId": {
"name": "device_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"subnetId": {
"name": "subnet_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"rackId": {
"name": "rack_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"rackDeviceId": {
"name": "rack_device_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"tagId": {
"name": "tag_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"ipId": {
"name": "ip_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"fieldId": {
"name": "field_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"userId": {
"name": "user_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"roleId": {
"name": "role_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"entityType": {
"name": "entity_type",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"device",
"subnet"
]
}
},
"tagIdentifier": {
"name": "tag_identifier",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "Tag name or numeric tag ID"
},
"ipAddress": {
"name": "ip_address",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "IPv4 address (e.g. 10.0.0.1)"
},
"auditLimit": {
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"default": 100
}
},
"auditOffset": {
"name": "offset",
"in": "query",
"schema": {
"type": "integer",
"default": 0
}
},
"auditUser": {
"name": "user",
"in": "query",
"schema": {
"type": "string"
},
"description": "Partial user name match"
},
"auditAction": {
"name": "action",
"in": "query",
"schema": {
"type": "string"
},
"description": "Exact action name"
},
"auditFrom": {
"name": "from",
"in": "query",
"schema": {
"type": "string",
"format": "date"
},
"description": "Start date YYYY-MM-DD"
},
"auditTo": {
"name": "to",
"in": "query",
"schema": {
"type": "string",
"format": "date"
},
"description": "End date YYYY-MM-DD"
}
},
"responses": {
"Unauthorized": {
"description": "Not authenticated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"Forbidden": {
"description": "Missing permission",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"NotFound": {
"description": "Resource not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"BadRequest": {
"description": "Invalid request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"security": [
{
"ApiKeyHeader": []
},
{
"BearerAuth": []
},
{
"ApiKeyQuery": []
},
{
"SessionCookie": []
}
],
"paths": {
"/auth/login": {
"post": {
"summary": "Log in with email and password",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginRequest"
}
}
}
},
"responses": {
"200": {
"description": "Login OK or 2FA required"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
},
"tags": [
"Authentication"
]
}
},
"/auth/logout": {
"post": {
"summary": "Log out and clear session",
"responses": {
"200": {
"description": "Session cleared",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
}
},
"tags": [
"Authentication"
]
}
},
"/auth/me": {
"get": {
"summary": "Current session, permissions, and org branding",
"responses": {
"200": {
"description": "Auth state"
}
},
"tags": [
"Authentication"
]
}
},
"/auth/verify-2fa": {
"post": {
"summary": "Complete login with TOTP or backup code",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Verify2faRequest"
}
}
}
},
"responses": {
"200": {
"description": "Login complete"
}
},
"tags": [
"Authentication"
]
}
},
"/auth/setup-2fa": {
"post": {
"summary": "Generate or verify TOTP setup",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Setup2faRequest"
}
}
}
},
"responses": {
"200": {
"description": "Secret/QR or setup complete"
}
},
"tags": [
"Authentication"
]
}
},
"/account": {
"get": {
"summary": "Account profile and 2FA status",
"security": [
{
"ApiKeyHeader": []
},
{
"BearerAuth": []
},
{
"ApiKeyQuery": []
},
{
"SessionCookie": []
}
],
"responses": {
"200": {
"description": "Account details"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
},
"tags": [
"Account"
]
}
},
"/account/change-password": {
"post": {
"summary": "Change password",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChangePasswordRequest"
}
}
}
},
"responses": {
"200": {
"description": "Password updated"
}
},
"tags": [
"Account"
]
}
},
"/account/disable-2fa": {
"post": {
"summary": "Disable two-factor authentication",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PasswordConfirmRequest"
}
}
}
},
"responses": {
"200": {
"description": "2FA disabled"
}
},
"tags": [
"Account"
]
}
},
"/account/regenerate-backup-codes": {
"post": {
"summary": "Regenerate 2FA backup codes",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PasswordConfirmRequest"
}
}
}
},
"responses": {
"200": {
"description": "New backup codes"
}
},
"tags": [
"Account"
]
}
},
"/info": {
"get": {
"summary": "API version and authenticated user info",
"responses": {
"200": {
"description": "API info"
}
},
"tags": [
"Info"
]
}
},
"/dashboard": {
"get": {
"summary": "Dashboard statistics and activity",
"responses": {
"200": {
"description": "Stats, subnet overview, activity timestamps"
}
},
"x-permission": "view_index",
"tags": [
"Dashboard"
]
}
},
"/search": {
"get": {
"summary": "Global search",
"parameters": [
{
"name": "q",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"description": "Search query"
}
],
"responses": {
"200": {
"description": "Matching subnets, IPs, devices, tags, racks, sites"
}
},
"tags": [
"Search"
]
}
},
"/devices": {
"get": {
"summary": "List devices",
"parameters": [
{
"name": "tag",
"in": "query",
"schema": {
"type": "string"
},
"description": "Filter by tag name"
},
{
"name": "site",
"in": "query",
"schema": {
"type": "string"
},
"description": "Filter by site (use Unassigned for null)"
}
],
"responses": {
"200": {
"description": "Device list",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ItemsResponse"
}
}
}
}
},
"x-permission": "view_devices",
"tags": [
"Devices"
]
},
"post": {
"summary": "Create device",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeviceCreate"
}
}
}
},
"responses": {
"201": {
"description": "Device created"
}
},
"x-permission": "add_device",
"tags": [
"Devices"
]
}
},
"/devices/{device_id}": {
"get": {
"summary": "Get device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"responses": {
"200": {
"description": "Device with IPs, tags, custom fields"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
},
"x-permission": "view_device",
"tags": [
"Devices"
]
},
"put": {
"summary": "Update device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeviceUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Device updated"
}
},
"x-permission": "edit_device",
"tags": [
"Devices"
]
},
"delete": {
"summary": "Delete device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"responses": {
"200": {
"description": "Device deleted"
}
},
"x-permission": "delete_device",
"tags": [
"Devices"
]
}
},
"/devices/{device_id}/ips": {
"post": {
"summary": "Assign IP to device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AssignIpRequest"
}
}
}
},
"responses": {
"201": {
"description": "IP assigned"
}
},
"x-permission": "add_device_ip",
"tags": [
"Devices"
]
}
},
"/devices/{device_id}/ips/{ip_id}": {
"delete": {
"summary": "Remove IP from device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
},
{
"$ref": "#/components/parameters/ipId"
}
],
"responses": {
"200": {
"description": "IP removed"
}
},
"x-permission": "remove_device_ip",
"tags": [
"Devices"
]
}
},
"/devices/{device_id}/ip-history": {
"get": {
"summary": "IP assignment history for device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"responses": {
"200": {
"description": "History items"
}
},
"x-permission": "view_device",
"tags": [
"Devices"
]
}
},
"/devices/{device_id}/custom-fields": {
"patch": {
"summary": "Update device custom field values",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomFieldsPatch"
}
}
}
},
"responses": {
"200": {
"description": "Fields updated"
}
},
"x-permission": "edit_device",
"tags": [
"Devices"
]
}
},
"/devices/{device_id}/tags": {
"get": {
"summary": "List tags on device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"responses": {
"200": {
"description": "Tags"
}
},
"x-permission": "view_device",
"tags": [
"Devices",
"Tags"
]
},
"post": {
"summary": "Assign tag to device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AssignTagRequest"
}
}
}
},
"responses": {
"200": {
"description": "Tag assigned"
}
},
"x-permission": "assign_device_tag",
"tags": [
"Devices",
"Tags"
]
}
},
"/devices/{device_id}/tags/{tag_id}": {
"delete": {
"summary": "Remove tag from device",
"parameters": [
{
"$ref": "#/components/parameters/deviceId"
},
{
"$ref": "#/components/parameters/tagId"
}
],
"responses": {
"200": {
"description": "Tag removed"
}
},
"x-permission": "remove_device_tag",
"tags": [
"Devices",
"Tags"
]
}
},
"/devices/by-tag/{tag_identifier}": {
"get": {
"summary": "List devices by tag name or ID",
"parameters": [
{
"$ref": "#/components/parameters/tagIdentifier"
},
{
"name": "format",
"in": "query",
"schema": {
"type": "string",
"enum": [
"simple"
]
},
"description": "simple returns [{device, ip}] array for devices with at least one IP"
}
],
"responses": {
"200": {
"description": "Devices (format varies by format param)"
}
},
"x-permission": "view_devices",
"tags": [
"Devices",
"Tags"
]
}
},
"/subnets": {
"get": {
"summary": "List subnets",
"parameters": [
{
"name": "include",
"in": "query",
"schema": {
"type": "string",
"enum": [
"utilization"
]
},
"description": "Include utilization stats when set to utilization"
}
],
"responses": {
"200": {
"description": "Subnet list"
}
},
"x-permission": "view_subnet",
"tags": [
"Subnets"
]
},
"post": {
"summary": "Create subnet",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SubnetCreate"
}
}
}
},
"responses": {
"201": {
"description": "Subnet created"
}
},
"x-permission": "add_subnet",
"tags": [
"Subnets"
]
}
},
"/subnets/{subnet_id}": {
"get": {
"summary": "Get subnet with IP addresses",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"responses": {
"200": {
"description": "Subnet detail"
}
},
"x-permission": "view_subnet",
"tags": [
"Subnets"
]
},
"put": {
"summary": "Update subnet",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SubnetUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Subnet updated"
}
},
"x-permission": "edit_subnet",
"tags": [
"Subnets"
]
},
"delete": {
"summary": "Delete subnet",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"responses": {
"200": {
"description": "Subnet deleted"
}
},
"x-permission": "delete_subnet",
"tags": [
"Subnets"
]
}
},
"/subnets/{subnet_id}/next_free_ip": {
"get": {
"summary": "First available IP outside DHCP pools",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"responses": {
"200": {
"description": "Next free IP"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
},
"x-permission": "view_subnet",
"tags": [
"Subnets"
]
}
},
"/subnets/{subnet_id}/available-ips": {
"get": {
"summary": "All unassigned IPs outside DHCP pools",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"responses": {
"200": {
"description": "Available IPs"
}
},
"x-permission": "view_subnet",
"tags": [
"Subnets"
]
}
},
"/subnets/{subnet_id}/export": {
"get": {
"summary": "Export subnet as CSV",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"responses": {
"200": {
"description": "CSV file",
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
},
"x-permission": "export_subnet_csv",
"tags": [
"Subnets"
]
}
},
"/subnets/{subnet_id}/custom-fields": {
"patch": {
"summary": "Update subnet custom field values",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomFieldsPatch"
}
}
}
},
"responses": {
"200": {
"description": "Fields updated"
}
},
"x-permission": "edit_subnet",
"tags": [
"Subnets"
]
}
},
"/subnets/{subnet_id}/dhcp": {
"get": {
"summary": "Get DHCP pools for subnet",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"responses": {
"200": {
"description": "DHCP pools"
}
},
"x-permission": "view_dhcp",
"tags": [
"DHCP"
]
},
"post": {
"summary": "Configure or remove DHCP pool",
"parameters": [
{
"$ref": "#/components/parameters/subnetId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DhcpConfigure"
}
}
}
},
"responses": {
"200": {
"description": "DHCP configured or removed"
}
},
"x-permission": "configure_dhcp",
"tags": [
"DHCP"
]
}
},
"/ip-addresses/{ip_id}": {
"patch": {
"summary": "Update IP address notes",
"parameters": [
{
"$ref": "#/components/parameters/ipId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IpNotesPatch"
}
}
}
},
"responses": {
"200": {
"description": "Notes updated"
}
},
"x-permission": "edit_subnet",
"tags": [
"IP Addresses"
]
}
},
"/ips/{ip_address}/history": {
"get": {
"summary": "IP assignment history",
"parameters": [
{
"$ref": "#/components/parameters/ipAddress"
}
],
"responses": {
"200": {
"description": "History for IP"
}
},
"x-permission": "view_subnet",
"tags": [
"IP Addresses"
]
}
},
"/tags": {
"get": {
"summary": "List tags",
"responses": {
"200": {
"description": "Tag list"
}
},
"x-permission": "view_tags",
"tags": [
"Tags"
]
},
"post": {
"summary": "Create tag",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TagCreate"
}
}
}
},
"responses": {
"201": {
"description": "Tag created"
}
},
"x-permission": "add_tag",
"tags": [
"Tags"
]
}
},
"/tags/{tag_id}": {
"get": {
"summary": "Get tag with devices",
"parameters": [
{
"$ref": "#/components/parameters/tagId"
}
],
"responses": {
"200": {
"description": "Tag detail"
}
},
"x-permission": "view_tags",
"tags": [
"Tags"
]
},
"put": {
"summary": "Update tag",
"parameters": [
{
"$ref": "#/components/parameters/tagId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TagUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Tag updated"
}
},
"x-permission": "edit_tag",
"tags": [
"Tags"
]
},
"delete": {
"summary": "Delete tag",
"parameters": [
{
"$ref": "#/components/parameters/tagId"
}
],
"responses": {
"200": {
"description": "Tag deleted"
}
},
"x-permission": "delete_tag",
"tags": [
"Tags"
]
}
},
"/racks": {
"get": {
"summary": "List racks",
"responses": {
"200": {
"description": "Rack list with devices"
}
},
"x-permission": "view_racks",
"tags": [
"Racks"
]
},
"post": {
"summary": "Create rack",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RackCreate"
}
}
}
},
"responses": {
"201": {
"description": "Rack created"
}
},
"x-permission": "add_rack",
"tags": [
"Racks"
]
}
},
"/racks/{rack_id}": {
"get": {
"summary": "Get rack",
"parameters": [
{
"$ref": "#/components/parameters/rackId"
}
],
"responses": {
"200": {
"description": "Rack detail"
}
},
"x-permission": "view_rack",
"tags": [
"Racks"
]
},
"put": {
"summary": "Update rack",
"parameters": [
{
"$ref": "#/components/parameters/rackId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RackUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Rack updated"
}
},
"x-permission": "add_rack",
"tags": [
"Racks"
]
},
"delete": {
"summary": "Delete rack",
"parameters": [
{
"$ref": "#/components/parameters/rackId"
}
],
"responses": {
"200": {
"description": "Rack deleted"
}
},
"x-permission": "delete_rack",
"tags": [
"Racks"
]
}
},
"/racks/{rack_id}/devices": {
"post": {
"summary": "Add device to rack position",
"parameters": [
{
"$ref": "#/components/parameters/rackId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RackDeviceCreate"
}
}
}
},
"responses": {
"201": {
"description": "Device placed in rack"
}
},
"x-permission": "add_device_to_rack",
"tags": [
"Racks"
]
}
},
"/racks/{rack_id}/devices/{rack_device_id}": {
"delete": {
"summary": "Remove device from rack",
"parameters": [
{
"$ref": "#/components/parameters/rackId"
},
{
"$ref": "#/components/parameters/rackDeviceId"
}
],
"responses": {
"200": {
"description": "Removed from rack"
}
},
"x-permission": "remove_device_from_rack",
"tags": [
"Racks"
]
}
},
"/racks/{rack_id}/export": {
"get": {
"summary": "Export rack layout as CSV",
"parameters": [
{
"$ref": "#/components/parameters/rackId"
}
],
"responses": {
"200": {
"description": "CSV file",
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
},
"x-permission": "export_rack_csv",
"tags": [
"Racks"
]
}
},
"/custom_fields/{entity_type}": {
"get": {
"summary": "List custom field definitions",
"parameters": [
{
"$ref": "#/components/parameters/entityType"
}
],
"responses": {
"200": {
"description": "Field definitions"
}
},
"x-permission": "view_custom_fields",
"tags": [
"Custom Fields"
]
}
},
"/custom_fields": {
"post": {
"summary": "Create custom field definition",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomFieldCreate"
}
}
}
},
"responses": {
"201": {
"description": "Field created"
}
},
"x-permission": "manage_custom_fields",
"tags": [
"Custom Fields"
]
}
},
"/custom_fields/{field_id}": {
"put": {
"summary": "Update custom field definition",
"parameters": [
{
"$ref": "#/components/parameters/fieldId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomFieldUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Field updated"
}
},
"x-permission": "manage_custom_fields",
"tags": [
"Custom Fields"
]
},
"delete": {
"summary": "Delete custom field definition",
"parameters": [
{
"$ref": "#/components/parameters/fieldId"
}
],
"responses": {
"200": {
"description": "Field deleted"
}
},
"x-permission": "manage_custom_fields",
"tags": [
"Custom Fields"
]
}
},
"/custom-fields/reorder": {
"post": {
"summary": "Reorder custom fields",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomFieldReorder"
}
}
}
},
"responses": {
"200": {
"description": "Order updated"
}
},
"x-permission": "manage_custom_fields",
"tags": [
"Custom Fields"
]
}
},
"/audit/actions": {
"get": {
"summary": "List distinct audit action names",
"responses": {
"200": {
"description": "Action names"
}
},
"x-permission": "view_audit",
"tags": [
"Audit"
]
}
},
"/audit": {
"get": {
"summary": "Query audit log",
"parameters": [
{
"$ref": "#/components/parameters/auditLimit"
},
{
"$ref": "#/components/parameters/auditOffset"
},
{
"$ref": "#/components/parameters/auditUser"
},
{
"$ref": "#/components/parameters/auditAction"
},
{
"$ref": "#/components/parameters/auditFrom"
},
{
"$ref": "#/components/parameters/auditTo"
}
],
"responses": {
"200": {
"description": "Paginated audit entries with total count"
}
},
"x-permission": "view_audit",
"tags": [
"Audit"
]
}
},
"/audit/export": {
"get": {
"summary": "Export audit log as CSV",
"parameters": [
{
"$ref": "#/components/parameters/auditUser"
},
{
"$ref": "#/components/parameters/auditAction"
},
{
"$ref": "#/components/parameters/auditFrom"
},
{
"$ref": "#/components/parameters/auditTo"
}
],
"responses": {
"200": {
"description": "CSV export",
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
},
"x-permission": "view_audit",
"tags": [
"Audit"
]
}
},
"/users": {
"get": {
"summary": "List users",
"responses": {
"200": {
"description": "User list (API keys not included)"
}
},
"x-permission": "view_users",
"tags": [
"Users"
]
},
"post": {
"summary": "Create user",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserCreate"
}
}
}
},
"responses": {
"201": {
"description": "User created"
}
},
"x-permission": "manage_users",
"tags": [
"Users"
]
}
},
"/users/{user_id}": {
"put": {
"summary": "Update user",
"parameters": [
{
"$ref": "#/components/parameters/userId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserUpdate"
}
}
}
},
"responses": {
"200": {
"description": "User updated"
}
},
"x-permission": "manage_users",
"tags": [
"Users"
]
},
"delete": {
"summary": "Delete user",
"parameters": [
{
"$ref": "#/components/parameters/userId"
}
],
"responses": {
"200": {
"description": "User deleted"
}
},
"x-permission": "manage_users",
"tags": [
"Users"
]
}
},
"/users/{user_id}/regenerate-api-key": {
"post": {
"summary": "Regenerate user API key",
"parameters": [
{
"$ref": "#/components/parameters/userId"
}
],
"responses": {
"200": {
"description": "New API key (shown once)"
}
},
"x-permission": "manage_users",
"tags": [
"Users"
]
}
},
"/roles": {
"get": {
"summary": "List roles with permissions",
"responses": {
"200": {
"description": "Roles"
}
},
"x-permission": "view_users",
"tags": [
"Roles"
]
},
"post": {
"summary": "Create role",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RoleCreate"
}
}
}
},
"responses": {
"201": {
"description": "Role created"
}
},
"x-permission": "manage_roles",
"tags": [
"Roles"
]
}
},
"/roles/{role_id}": {
"put": {
"summary": "Update role",
"parameters": [
{
"$ref": "#/components/parameters/roleId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RoleUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Role updated"
}
},
"x-permission": "manage_roles",
"tags": [
"Roles"
]
},
"delete": {
"summary": "Delete role",
"parameters": [
{
"$ref": "#/components/parameters/roleId"
}
],
"responses": {
"200": {
"description": "Role deleted"
}
},
"x-permission": "manage_roles",
"tags": [
"Roles"
]
}
},
"/permissions": {
"get": {
"summary": "List all permissions",
"responses": {
"200": {
"description": "Permission definitions"
}
},
"x-permission": "manage_roles",
"tags": [
"Permissions"
]
}
},
"/settings": {
"get": {
"summary": "Get organisation settings",
"responses": {
"200": {
"description": "org_name, org_logo, accent_color"
}
},
"x-permission": "view_settings",
"tags": [
"Settings"
]
},
"put": {
"summary": "Update organisation settings",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettingsUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Settings saved"
}
},
"x-permission": "manage_settings",
"tags": [
"Settings"
]
}
},
"/bulk/assign-ips": {
"post": {
"summary": "Bulk assign IPs to a device",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkAssignIps"
}
}
}
},
"responses": {
"200": {
"description": "Per-IP success and failure lists"
}
},
"x-permission": "add_device_ip",
"tags": [
"Bulk"
]
}
},
"/bulk/create-devices": {
"post": {
"summary": "Bulk create devices",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkCreateDevices"
}
}
}
},
"responses": {
"200": {
"description": "Per-device success and failure lists"
}
},
"x-permission": "add_device",
"tags": [
"Bulk"
]
}
},
"/bulk/assign-tags": {
"post": {
"summary": "Bulk assign tag to devices",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkAssignTags"
}
}
}
},
"responses": {
"200": {
"description": "Per-device success and failure lists"
}
},
"x-permission": "assign_device_tag",
"tags": [
"Bulk"
]
}
},
"/bulk/export-subnets": {
"post": {
"summary": "Export multiple subnets as CSV",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkExportSubnets"
}
}
}
},
"responses": {
"200": {
"description": "Combined CSV export",
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
},
"x-permission": "export_subnet_csv",
"tags": [
"Bulk"
]
}
}
}
}