Admin Endpoints¶
All admin endpoints require Admin Authentication (IP whitelist + HMAC signature).
Base Path: /api/v1/admin
User Management¶
Create User¶
Endpoint: POST /api/v1/admin/users
Request Body:
Response (201 Created):
{
"user_id": 12345,
"api_token": "generated_token_here",
"is_active": true,
"created_at": "2026-04-27T10:00:00Z"
}
Error Responses:
409 Conflict: User already exists
Get User¶
Endpoint: GET /api/v1/admin/users/{user_id}
Response (200 OK):
Error Responses:
404 Not Found: User not found
Update User Status¶
Endpoint: PATCH /api/v1/admin/users/{user_id}
Request Body:
Response (200 OK): Same as Get User
Delete User¶
Endpoint: DELETE /api/v1/admin/users/{user_id}
Response (204 No Content): Empty body
Notes: Cascades — deletes all subscriptions, provider connections, and related data owned by the user.
Refresh User Token¶
Generate a new API token for a user, invalidating the old one.
Endpoint: POST /api/v1/admin/users/{user_id}/refresh-token
Response (200 OK):
Provider Management¶
Create Provider¶
Endpoint: POST /api/v1/admin/providers
Request Body:
{
"owner_hash": "user_hash_here",
"provider_name": "MyProvider",
"provider_url": "https://myprovider.com"
}
Response (201 Created):
{
"provider_hash": "generated_hash",
"provider_name": "MyProvider",
"provider_url": "https://myprovider.com",
"api_token": "provider_api_token",
"is_active": true,
"created_at": "2026-04-27T10:00:00Z"
}
List All Providers¶
Endpoint: GET /api/v1/admin/providers
Response (200 OK):
Get Provider by Name¶
Endpoint: GET /api/v1/admin/providers/by-name/{provider_name}
Response (200 OK): Same as Create Provider response
Get Provider by Owner¶
Endpoint: GET /api/v1/admin/providers/by-owner/{owner_id}
Response (200 OK): Same as Create Provider response
Update Provider Status¶
Endpoint: PATCH /api/v1/admin/providers/{provider_hash}
Request Body:
Response (200 OK): Same as Create Provider response
Delete Provider¶
Endpoint: DELETE /api/v1/admin/providers/{provider_hash}
Response (204 No Content): Empty body
Notes: Cascades — deletes all subscriptions managed by this provider.
Refresh Provider Token¶
Endpoint: POST /api/v1/admin/providers/{provider_hash}/refresh-token
Response (200 OK):
Provider Authorization Management¶
Process Authorization Request¶
Manually process a provider authorization request (typically called by the provider's system after receiving an HMAC-signed invite).
Endpoint: POST /api/v1/admin/providers/{provider_name}/authorize/{user_id}
Request Body:
Response (200 OK):
Get User's Providers¶
Endpoint: GET /api/v1/admin/users/{user_id}/providers
Response (200 OK): Same shape as List My Provider Connections
Get Specific User-Provider Connection¶
Endpoint: GET /api/v1/admin/users/{user_id}/providers/{provider_name}
Response (200 OK): Same shape as Get Specific Provider Connection
Approve Provider Authorization¶
Endpoint: POST /api/v1/admin/users/{user_id}/providers/{provider_name}/approve
Response (200 OK): Same shape as Get Specific Provider Connection, with status: "approved"
Error Responses:
409 Conflict: Not in pending status, or user has reachedMAX_PROVIDERS_PER_USER
Reject Provider Authorization¶
Endpoint: POST /api/v1/admin/users/{user_id}/providers/{provider_name}/reject
Response (200 OK): Same shape as Get Specific Provider Connection
Notes: Same delete-vs-revoke behavior as Reject Provider Connection.
Error Responses:
409 Conflict: Not in pending status
IP Ban Management¶
Ban IP Address¶
Endpoint: POST /api/v1/admin/ban
Request Body:
duration_seconds is optional; if omitted, the server's default ban duration is used.
Response (201 Created):
{
"ip_address": "192.168.1.100",
"banned_until": "2026-04-27T11:00:00Z",
"remaining_seconds": 3600
}
Check Ban Status¶
Endpoint: GET /api/v1/admin/ban/{ip_address}
Response (200 OK):
{
"ip_address": "192.168.1.100",
"is_banned": true,
"banned_until": "2026-04-27T11:00:00Z",
"remaining_seconds": 1800
}
Unban IP Address¶
Endpoint: DELETE /api/v1/admin/ban/{ip_address}
Response (200 OK):
was_banned is false if the address wasn't actually banned — safe to call unconditionally.
List All Bans¶
Endpoint: GET /api/v1/admin/bans
Response (200 OK):
{
"total": 2,
"entries": [
{
"ip_address": "192.168.1.100",
"banned_until": "2026-04-27T11:00:00Z"
},
{
"ip_address": "203.0.113.5",
"banned_until": "2026-04-27T12:00:00Z"
}
]
}
Whitelist Management¶
Whitelisted ranges take precedence over bans and are exempt from IP-based rate limiting.
Add to Whitelist¶
Endpoint: POST /api/v1/admin/whitelist
Request Body:
Response (201 Created):
List Whitelist¶
Endpoint: GET /api/v1/admin/whitelist
Response (200 OK):
{
"entries": [
{
"ip_address": "10.0.0.0/24",
"description": "Office network",
"added_at": "2026-04-27T10:00:00Z"
}
]
}
Remove from Whitelist¶
Endpoint: DELETE /api/v1/admin/whitelist/{ip_address}
Response (200 OK):
Usage Statistics¶
Endpoint: GET /api/v1/admin/stats
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
period |
string | No | Predefined period: day, week, or month |
start_date |
string | No | ISO 8601 start of an explicit range |
end_date |
string | No | ISO 8601 end of an explicit range |
Omit all parameters to use the API's default range. period and an explicit start_date/end_date range are mutually exclusive ways of specifying the same thing.
Response (200 OK):
{
"period": {
"start": "2026-04-20T00:00:00Z",
"end": "2026-04-27T00:00:00Z"
},
"total_requests": 154302,
"total_subscriptions": 421,
"total_users": 98,
"total_providers": 6
}
The exact set of fields returned may be extended over time; treat unknown fields as informational.