Public developer area for Security Center.
This page explains how remote websites, backend services, local assistants and automation tools can call the MEDPOV Security Center API. The API is designed for querying security events, building IP profiles, watching live traffic, reading system health and running authorized POST actions.
Auth and connection standard
Create the API key from the Remote API Access section on the Settings page. The key is shown as plain text only once when created; afterwards it is stored as a hash.
Recommended header
Authorization: Bearer mpsec_YOUR_API_KEY
Accept: application/jsonAlternatively, X-MEDPOV-API-Key: mpsec_YOUR_API_KEY or X-API-Key can be used. ?api_key=... may be supported through the query string, but header-based usage is safer in production because public URL logs can expose query values.
HTTP and response rules
- All responses return application/json; charset=utf-8.
- GET actions read information; POST actions modify IP rules or event status.
- CORS headers are enabled, but the API key must not be embedded in browser-side code.
- Successful responses usually return ok: true; errors return ok: false.
Queryable commands
These actions can be called from a remote system or local assistant. Read actions work with GET.
Map access and Friday map commands
The map endpoint follows the same logic as the Global Threat Map in the admin dashboard. Friday can read attack locations, live visitor points, trace lines going to the protected target and click-popup fields from this JSON response.
Map mode options
GET action=map&mode=threat&threat_range=24hOnly attack locations, threat markers, attack trace lines and threat popup fields.GET action=map&mode=live&live_range=liveActive heartbeat visitors, live markers, visitor trace lines and live popup fields.GET action=map&mode=both&live_range=liveThreat and Live layers are both active in the same map response.GET action=both-map&include_curve_points=1Shortcut alias; Friday can redraw the curved lines with curve_points.GET action=map&mode=both&include_curve_points=0Lighter response; line from/to + style is returned without curve points.{
"ok": true,
"access": "map-intelligence",
"mode": "both",
"target": { "lat": 41.0082, "lng": 28.9784, "label": "Protected Origin" },
"threat_events": [],
"live_users": [],
"layers": {
"threat": { "enabled": true, "points": [], "traces": [], "popups": [] },
"live": { "enabled": true, "points": [], "traces": [], "popups": [] }
},
"map": {
"provider": "leaflet",
"active_layers": ["threat", "live"],
"popup_contract": {}
}
}Authorized POST actions
These commands modify the system. They should only be called from a trusted backend, local assistant or automation service.
Remote website call examples
The endpoint remains fixed; only action and parameters change. In the examples below, replace mpsec_YOUR_API_KEY with the key generated from Settings.
curl -X GET 'https://testsc.medpov.com/admin/api/remote-access.php?action=overview' \
-H 'Authorization: Bearer mpsec_YOUR_API_KEY' \
-H 'Accept: application/json'curl -X POST 'https://testsc.medpov.com/admin/api/remote-access.php?action=block-ip' \
-H 'Authorization: Bearer mpsec_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"ip":"203.0.113.45","minutes":1440,"reason":"Remote confirmed abusive traffic"}'<?php
function medpov_security_api(string $endpoint, string $apiKey, string $action, array $params = [], string $method = 'GET'): array
{
$method = strtoupper($method);
$url = $endpoint . '?action=' . rawurlencode($action);
$headers = [
'Authorization: Bearer ' . $apiKey,
'Accept: application/json',
];
$body = null;
if ($method === 'GET' && $params) {
$url .= '&' . http_build_query($params);
} elseif ($params) {
$headers[] = 'Content-Type: application/json';
$body = json_encode($params, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 20,
CURLOPT_CONNECTTIMEOUT => 8,
]);
if ($body !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
$raw = curl_exec($ch);
$error = curl_error($ch);
$status = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($raw === false || $raw === '') {
return ['ok' => false, 'status' => $status, 'message' => $error ?: 'Empty API response'];
}
$json = json_decode($raw, true);
if (!is_array($json)) {
return ['ok' => false, 'status' => $status, 'message' => 'Invalid JSON response', 'raw' => $raw];
}
$json['_http_status'] = $status;
return $json;
}
$endpoint = 'https://example.com/security-center/admin/api/remote-access.php';
$apiKey = 'mpsec_YOUR_API_KEY';
$overview = medpov_security_api($endpoint, $apiKey, 'overview');
$ipProfile = medpov_security_api($endpoint, $apiKey, 'ip-profile', ['ip' => '203.0.113.12', 'refresh' => 1]);
$block = medpov_security_api($endpoint, $apiKey, 'block-ip', [
'ip' => '203.0.113.45',
'minutes' => 1440,
'reason' => 'Remote confirmed abusive traffic',
], 'POST');const endpoint = 'https://example.com/security-center/admin/api/remote-access.php';
const apiKey = process.env.MEDPOV_SECURITY_API_KEY;
async function securityApi(action, params = {}, method = 'GET') {
const url = new URL(endpoint);
url.searchParams.set('action', action);
const options = {
method,
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: 'application/json'
}
};
if (method === 'GET') {
Object.entries(params).forEach(([key, value]) => url.searchParams.set(key, String(value)));
} else {
options.headers['Content-Type'] = 'application/json';
options.body = JSON.stringify(params);
}
const res = await fetch(url, options);
const data = await res.json();
if (!res.ok || data.ok === false) throw new Error(data.message || `API error ${res.status}`);
return data;
}
const overview = await securityApi('overview');
const mapBoth = await securityApi('map', { mode: 'both', live_range: 'live', include_curve_points: 1 });
const critical = await securityApi('events', { risk: 'CRITICAL', resolved: 0, limit: 20 });Example response format
Each action returns its own detail fields; the shared success/error logic is shown below.
{
"ok": true,
"server_time": "2026-05-04 21:30:00",
"version": "6.0.8-13-test",
"stats": {},
"recommendations_tr": [],
"available_actions": {}
}{
"ok": true,
"access": "map-intelligence",
"mode": "both",
"target": { "lat": 41.0082, "lng": 28.9784, "label": "Protected Origin" },
"threat_events": [],
"live_users": [],
"layers": {
"threat": { "enabled": true, "points": [], "traces": [], "popups": [] },
"live": { "enabled": true, "points": [], "traces": [], "popups": [] }
},
"map": {
"provider": "leaflet",
"active_layers": ["threat", "live"],
"popup_contract": {}
}
}{
"ok": false,
"message": "Unauthorized",
"hint": "Send Authorization: Bearer <api-key> or X-MEDPOV-API-Key."
}Local assistant / automation command mapping
Friday or a similar local assistant can translate user commands into the API actions below.
GET action=overviewGET action=events&risk=CRITICAL&resolved=0&limit=20GET action=threat-map&threat_range=24hGET action=live-map&live_range=liveGET action=both-map&live_range=live&include_curve_points=1GET action=ip-profile&ip=203.0.113.12&refresh=1GET action=event&id=123POST action=block-ip body: ip, minutes=1440, reasonPOST action=resolve-ip-events body: ip, status=remote_ip_resolvedGET action=healthSecure usage
Store the API key only in a server-side environment variable. If the key leaks, disable it from Settings and generate a new one.
Rate and timeout
Use an 8-20 second timeout, short-lived cache and controlled retry on the remote helper side. Do not call health/overview in an endless loop.
Recommended flow
Start with ping, then overview. If there is risk, call events or ip-profile. Use POST actions only when necessary.
https://testsc.medpov.com/developer-api.php. The API endpoint is https://testsc.medpov.com/admin/api/remote-access.php.