1. What you get
A live answer to “is Manager.Social healthy right now?” plus the detail behind it: the database, queues, email, payments, data providers, the server's disk and memory, and more. You also get a short history, so you can see when something went wrong and for how long. It is read-only and carries no business data: no users, companies or numbers about customers.
2. Getting access
Only the Super Admin can give you access. They create a Health key for you, tick the health parameters you may see, and send you a client id and a client secret. The secret is shown only once, so keep it safe. You can only ever read the parameters that were ticked for you, and the Super Admin can take access away at any time.
3. Logging in
There are two ways. Use whichever your tool supports.
Bearer token. Swap your id and secret for a token, then send it with every call. A token lasts a limited time; when it expires, ask for a new one.
curl -s -X POST 'https://manager.social/metrics-exchange/v1/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>'The answer contains access_token. Send it as Authorization: Bearer <token>.
Basic login. On the monitor routes you can skip the token and sendAuthorization: Basic base64(client_id:client_secret) on every call. This is the easiest choice for uptime tools, which usually have a “username and password” box: put the client id in the first and the secret in the second.
4. The four calls
All paths start with https://manager.social/metrics-exchange/v1.
GET /monitor — the full picture
The current state of every parameter ticked for you. overall is the worst level among them.reason is normally empty; it says checks_not_running when the app's own checks have stopped (the data is old), and then overall is critical. Each parameter has a stale flag that is true when its reading is older than it should be. Add ?params=id1,id2 to ask for just some.
curl -s 'https://manager.social/metrics-exchange/v1/monitor' -H 'Authorization: Bearer <token>'{
"overall": "warning",
"reason": null,
"checkedAt": "2026-11-06T09:41:00Z",
"params": [
{
"id": "server.disk", "group": "server", "label": "Disk",
"level": "warning", "value": 83, "unit": "percent", "detail": null,
"since": "2026-11-05T22:10:00Z", "checkedAt": "2026-11-06T09:41:00Z", "stale": false
}
]
}GET /monitor/ping — one word, for machines
Returns { "overall": "…" }. The HTTP status is 200 unless the overall level is critical, in which case it is 503. That makes it perfect for an uptime tool: it only has to check the status code.
curl -s -o /dev/null -w '%{http_code}\n' 'https://manager.social/metrics-exchange/v1/monitor/ping' \
-H 'Authorization: Basic <base64 of client_id:client_secret>'
# or let curl do the encoding:
curl -s -u '<client_id>:<client_secret>' 'https://manager.social/metrics-exchange/v1/monitor/ping'{ "overall": "ok" }GET /monitor/history — what happened
Per parameter, how many minutes it spent at each level, grouped by group=hour (up to the last 7 days) or group=day (up to the last 400 days). Use from and to (a date or date-time); without them you get the last 24 hours (hour) or 30 days (day). The uptime percentage is (ok + warning minutes) ÷ minutes with a known level; minutes in planned maintenance are left out.
curl -s -u '<client_id>:<client_secret>' \
'https://manager.social/metrics-exchange/v1/monitor/history?params=server.disk,infra.postgres&group=hour&from=2026-11-05'{
"from": "2026-11-05T00:00:00Z", "to": "2026-11-06T09:45:00Z", "group": "hour",
"params": [
{
"id": "server.disk",
"buckets": [
{
"start": "2026-11-05T00:00:00Z", "end": "2026-11-05T01:00:00Z",
"minutes": { "ok": 60, "warning": 0, "critical": 0, "unknown": 0, "maintenance": 0 },
"uptimePercent": 100, "avg": 54.3, "max": 54.9
}
]
}
]
}start / end— The bucket's first instant and the instant after its last (UTC); an hour or a day long.minutes— Minutes the parameter spent at each level in the bucket: ok, warning, critical, unknown, maintenance.uptimePercent— (ok + warning) / (ok + warning + critical) x 100; null when no minute had a known level. Maintenance and unknown minutes are left out.avg— Average measured value in the bucket, in the parameter's unit; null for state-only parameters or no data.max— Highest measured value in the bucket; null when there is none.
GET /monitor/catalogue — what you can see
Lists your parameters with their description, thresholds and how often each is checked. Handy for building your own dashboard labels.
curl -s -u '<client_id>:<client_secret>' 'https://manager.social/metrics-exchange/v1/monitor/catalogue'5. What the levels mean
| Level | Meaning |
|---|---|
ok | Working normally. |
warning | Still working, but something is getting close to a limit. Look at it soon. |
critical | Broken or about to break. Act now. |
unknown | The app could not tell. It is not counted as a failure, but look into it. |
maintenance | A planned maintenance window is on, so a bad reading is expected. |
Treat no answer, a timeout or any 5xx as critical. If the app is down it cannot tell you so, so silence is the loudest alarm there is.
value and detail are the latest raw reading, while level is the held (confirmed) level: a new level must be seen a few checks in a row before it replaces the old one, so for a minute or two they can disagree (for example 70 % used with level warning).
Inside the app, a warning or critical that lasts sends the Super Admins a reminder every 6 hours; each Super Admin can mute that per event in Notification settings.
6. How often to ask
/monitor/pingevery 1 to 2 minutes./monitorevery 5 minutes, for the detail./monitor/historyonly when you need a report; it does not change faster than hourly buckets.
Every call counts against your daily allowance (see Errors and limits), so there is no benefit in asking more often than the app checks.
7. Using an uptime tool
Works with UptimeRobot and similar tools. Create an HTTP(s) monitor:
- URL:
https://manager.social/metrics-exchange/v1/monitor/ping - Authentication: Basic. Username = your client id, password = your client secret.
- Check every 1 to 2 minutes (5 minutes on a free plan is fine).
- Expect HTTP status 200. Optionally add a keyword check for
"overall":"ok"if you also want to be told about warnings. - Send alerts to the people who should wake up. A 503, a timeout or no answer is a real outage.
8. Every parameter
You see only the ones ticked for your key. Thresholds: for most parameters a higher number is worse; for the SSL certificate a lower number is worse. A parameter with no thresholds reports its own state.
Services
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
component.website | The web app answers (status page state). | state | Reports its own state | 1 min |
component.sign_in | Login works (status page state). | state | Reports its own state | 1 min |
component.api | The API answers (status page state). | state | Reports its own state | 1 min |
component.seo_data | SEO data providers work (status page state). | state | Reports its own state | 1 min |
component.social_publishing | Scheduled posts go out (status page state). | state | Reports its own state | 1 min |
component.short_links | Short links and OneLink work (status page state). | state | Reports its own state | 1 min |
Infrastructure
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
infra.postgres | Database ping and latency. | ms | Warning ≥ 1000 ms · Critical ≥ 4000 ms | 1 min |
infra.postgres_connections | Used share of the maximum database connections. | percent | Warning ≥ 80 % · Critical ≥ 90 % | 1 min |
infra.migrations | Failed or unfinished Prisma migrations. | count | Critical ≥ 1 | 15 min |
infra.redis_cache | Cache Redis ping time. | ms | Warning ≥ 500 ms | 1 min |
infra.redis_queue | Queue Redis ping time. | ms | Warning ≥ 500 ms | 1 min |
infra.meilisearch | Meilisearch ping time. | ms | Warning ≥ 1000 ms | 1 min |
infra.minio | MinIO ping time. | ms | Warning ≥ 1000 ms | 1 min |
Background jobs
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
jobs.failed_24h | Failed background jobs across the main queues in the last 24 hours. | count | Warning ≥ 10 · Critical ≥ 50 | 1 min |
jobs.backlog | Waiting jobs plus delayed jobs that are overdue. | count | Warning ≥ 500 · Critical ≥ 2000 | 1 min |
jobs.scheduler | Minutes since the every-minute status job last ran. | minutes | Warning ≥ 5 min · Critical ≥ 15 min | 1 min |
Server
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
server.disk | Root disk used. | percent | Warning ≥ 80 % · Critical ≥ 90 % | 1 min |
server.memory | RAM used. | percent | Warning ≥ 85 % · Critical ≥ 95 % | 1 min |
server.cpu_load | 5-minute load average divided by cores. | ratio | Warning ≥ 1.5 · Critical ≥ 3 | 1 min |
server.processes | api-server and ms-web online; restarts in the last hour. | count | Warning ≥ 2 · Critical ≥ 4 | 1 min |
server.ssl | Days until the public site's certificate ends. | days | Warning ≤ 14 days · Critical ≤ 3 days | 1 h |
server.backup | Hours since the newest database dump. | hours | Warning ≥ 26 h · Critical ≥ 50 h | 15 min |
Traffic
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
api.errors | Share of API responses that were 5xx in the last 5 minutes. | percent | Warning ≥ 1 % · Critical ≥ 5 % | 1 min |
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
email.stuck | Emails still queued or pending after 15 minutes (last 24 hours). | count | Warning ≥ 5 · Critical ≥ 20 | 1 min |
email.failure_rate | Failed or refused sends divided by all send attempts in the last hour. | percent | Warning ≥ 10 % · Critical ≥ 25 % | 1 min |
email.config | Primary WiredMessage is on and the alert purpose is mapped. | state | Reports its own state | 15 min |
Payments
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
payments.invoice_sync | Completed purchases of the last 30 days whose eSimplified invoice sync failed. | count | Warning ≥ 1 | 5 min |
payments.mismatch | Payment-recovery mismatches reported in the last 24 hours. | count | Warning ≥ 1 | 5 min |
Data providers
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
provider.dataforseo | Failed share of DataForSEO calls in the last 15 minutes. | percent | Warning ≥ 10 % · Critical ≥ 50 % | 1 min |
provider.serper | Failed share of Serper calls in the last 15 minutes. | percent | Warning ≥ 10 % · Critical ≥ 50 % | 1 min |
provider.google_ads | Failed share of Google Ads calls in the last 15 minutes. | percent | Warning ≥ 10 % · Critical ≥ 50 % | 1 min |
provider.ai | A primary AI provider is set and its last test passed. | state | Reports its own state | 15 min |
Maintenance
| Id | What it measures | Unit | Levels | Checked every |
|---|---|---|---|---|
maintenance.active | A planned window or deploy maintenance is on now (information only). | state | Reports its own state | 1 min |
9. Errors and limits
| Code | HTTP | What it means |
|---|---|---|
TOKEN_EXPIRED | 401 | Your token ran out or was revoked. Ask for a new one (or use Basic login). |
CLIENT_DISABLED | 403 | The Super Admin switched your access off. |
SCOPE_DISABLED | 403 | The health switch is off for the whole platform. |
MX_WRONG_CLIENT_KIND | 403 | This key is not a health key (or you used a health key on a business-data route). |
MX_PARAM_NOT_ALLOWED | 403 | You asked for a parameter that is not ticked for your key. |
MX_UNKNOWN_PARAM | 400 | You asked for a parameter that does not exist. |
INVALID_RANGE | 400 | A bad from/to/group in /monitor/history. |
RATE_LIMITED | 429 | Too many calls today. The Retry-After header says how many seconds to wait. |
By default a health key may make 3,000 calls a day (the Super Admin can change this for your key). Past that you get 429 with a Retry-After header: wait that many seconds. A call to/ping that returns 503 still counts, because it is a valid answer.
10. When access stops
If your calls start failing with 401 or 403, it is almost always one of these. Ask the Super Admin to check:
- your key was disabled;
- your secret was revoked or replaced (you need the new one);
- the parameters ticked for you were changed;
- the platform's health switch is off.
If instead you get a 5xx or no answer at all, treat it as critical: the app itself may be down.