Web UI API Reference
The Web UI exposes REST endpoints for programmatic access to admin features.
Authentication
The Web UI uses cookie-based authentication. Set WebUi__AdminApiKey to enable.
Login
POST /ui/api/auth
Content-Type: application/json
{
"apiKey": "your-admin-api-key"
}Response:
{
"ok": true,
"expires": "2025-01-01T00:00:00Z"
}Sets the portway_auth cookie.
Endpoints
GET /ui/api/overview
Dashboard overview data.
GET /ui/api/overview
Authorization: Bearer {token}Response:
{
"version": "1.0.0+build.123",
"uptime_seconds": 3600,
"endpoints": {
"sql": 5,
"proxy": 3,
"static": 2,
"files": 1,
"webhooks": 2
},
"environments": ["dev", "test", "prod"],
"server_name": "localhost"
}GET /ui/api/endpoints
All configured endpoints grouped by type.
GET /ui/api/endpoints
Authorization: Bearer {token}Response:
{
"sql": [
{
"name": "Products",
"namespace": "Catalog",
"path": "endpoints/SQL/Catalog/Products/entity.json",
"schema": "dbo",
"primary_key": "ProductId",
"allowed_columns": ["ProductId", "Name", "Price"]
}
],
"proxy": [...],
"static": [...],
"files": [...],
"webhooks": [...]
}GET /ui/api/environments
Environment configuration.
GET /ui/api/environments
Authorization: Bearer {token}Response:
{
"server_name": "localhost",
"allowed_environments": ["dev", "test", "prod"],
"environments": {
"dev": { "connection_string": "..." },
"prod": { "connection_string": "..." }
}
}PATCH /ui/api/environments
Update environment configuration.
PATCH /ui/api/environments
Authorization: Bearer {token}
Content-Type: application/json
{
"allowed_environments": ["dev", "staging", "prod"],
"environments": {
"dev": { "connection_string": "Server=dev;..." },
"prod": { "connection_string": "Server=prod;..." }
}
}GET /ui/api/settings
Full application settings dump.
GET /ui/api/settings
Authorization: Bearer {token}Response:
{
"rate_limiting": {
"enabled": true,
"ip_limit": 100,
"ip_window_seconds": 60,
"token_limit": 100,
"token_window_seconds": 60
},
"caching": {
"enabled": true,
"provider": "Memory",
"default_duration_seconds": 300
},
"sql_pooling": {
"enabled": true,
"min_pool_size": 5,
"max_pool_size": 100
},
"logging": {
"min_level": "Information",
"sinks": ["Console", "File"]
}
}GET /ui/api/tokens
List API tokens.
GET /ui/api/tokens
Authorization: Bearer {token}GET /ui/api/tokens?include_revoked=true
Authorization: Bearer {token}Response:
[
{
"id": 1,
"username": "api-user",
"description": "Production API",
"created_at": "2025-01-01 00:00:00",
"expires_at": null,
"revoked_at": null,
"allowed_scopes": "*",
"allowed_environments": "*",
"is_active": true
}
]POST /ui/api/tokens
Create a new token.
POST /ui/api/tokens
Authorization: Bearer {token}
Content-Type: application/json
{
"username": "new-user",
"description": "Read-only access",
"allowed_scopes": "read",
"allowed_environments": "dev,test",
"expires_in_days": 90
}Response:
{
"ok": true,
"token": {
"token": "pw_abc123...",
"username": "new-user",
"expires_at": "2025-04-01T00:00:00Z"
}
}PUT /ui/api/tokens/{id}
Update token properties.
PUT /ui/api/tokens/1
Authorization: Bearer {token}
Content-Type: application/json
{
"allowed_scopes": "read,write",
"allowed_environments": "dev,test,prod",
"description": "Updated description",
"expires_at": "2025-06-01T00:00:00Z"
}DELETE /ui/api/tokens/{id}
Revoke a token.
DELETE /ui/api/tokens/1
Authorization: Bearer {token}Response:
{
"ok": true
}POST /ui/api/tokens/
Rotate (revoke and recreate) a token.
POST /ui/api/tokens/1/rotate
Authorization: Bearer {token}Response:
{
"ok": true,
"token": {
"token": "pw_xyz789...",
"username": "api-user"
}
}POST /ui/api/tokens/
Unarchive a revoked token.
POST /ui/api/tokens/1/unarchive
Authorization: Bearer {token}GET /ui/api/tokens/
Get token audit log.
GET /ui/api/tokens/1/audit
Authorization: Bearer {token}Response:
[
{
"operation": "Created",
"timestamp": "2025-01-01 00:00:00",
"details": "Token created",
"ip_address": "192.168.1.1",
"user_agent": "Portway/1.0"
},
{
"operation": "Revoked",
"timestamp": "2025-01-15 00:00:00",
"details": "Revoked by admin",
"ip_address": "192.168.1.1",
"user_agent": "Portway/1.0"
}
]GET /ui/api/logs
Browse application logs.
GET /ui/api/logs?page=1&limit=50
Authorization: Bearer {token}Query Parameters:
| Parameter | Default | Description |
|-----------|---------|-------------|
| page | 1 | Page number |
| limit | 50 | Items per page (max 100) |
| level | - | Filter by level (Debug, Information, Warning, Error) |
| search | - | Search in message |
Response:
{
"page": 1,
"total_pages": 10,
"logs": [
{
"timestamp": "2025-01-01T10:30:00.000Z",
"level": "Information",
"message": "Application started",
"source": "Program"
}
]
}GET /ui/api/events
Server-Sent Events stream for real-time updates.
GET /ui/api/eventsEvents:
event: health
data: {"status":"Healthy"}event: endpoint_reload
data: {"type":"sql","count":5}SSE Events
The UI subscribes to real-time updates via Server-Sent Events.
Event Types
| Event | Data | Description |
|---|---|---|
health |
{status: "Healthy|Degraded|Unhealthy"} |
Health status change |
endpoint_reload |
{type, count} |
Endpoints reloaded |
token_created |
{id, username} |
New token created |
token_revoked |
{id, username} |
Token revoked |
Error Responses
401 Unauthorized
{
"error": "Unauthorized",
"message": "Valid authentication required"
}403 Forbidden
{
"error": "Access denied",
"clientIp": "192.168.1.100",
"requestedPath": "/ui/dashboard"
}404 Not Found
{
"error": "Not found",
"message": "Resource does not exist"
}409 Conflict
{
"error": "Conflict",
"message": "Token with this username already exists"
}Rate Limiting
UI API endpoints are subject to rate limiting. Returns 429 Too Many Requests when exceeded.