Link health
See whether your links' destinations still work, check one now, or ignore one.
We visit the destination of every live link on a schedule: popular links daily, quieter ones weekly or monthly. A failure only counts once two checks in a row fail. status is NotChecked, Working, Warning (works, but with a long chain of redirects or a site that refuses automated checks), Broken (an error such as 404), Unreachable (no answer, or a certificate problem), DomainGone, PrivateAddress or Unsafe (redirects to a page listed by automatic screening). The guide is at /docs/link-health.
Every path below starts with https://bgum.me/api/v1/workspaces/{workspaceId}. Send your API key in the Authorization header as described in the API overview.
| Operation | Method and path |
|---|---|
| List link health | GET /link-health |
| Get a link's health | GET /links/{linkId}/health |
| Check a link now | POST /links/{linkId}/health/check |
| Ignore a link | PUT /links/{linkId}/health/ignored |
List link health
GET /link-health
Lists links with their destination health, most clicked first. By default only the ones that need a look.
- Full path
/api/v1/workspaces/{workspaceId}/link-health- API key scope
-
links:read - Role needed
- Viewer or above
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspaceId |
string | Yes | Your workspace ID, from Settings → Workspace. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
filter |
string | No | Problems (not working or with a warning, the default), Failing, Warnings, Working, NotChecked, Ignored or All. |
page |
integer | No | Page number, from 1. Default 1. |
pageSize |
integer | No | Links per page, 1 to 100. Default 25. |
Example request
curl
curl "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/link-health?filter=Failing" \
-H "Authorization: Bearer $BGL_API_KEY"
JavaScript
const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/link-health?filter=Failing`, {
headers: {
Authorization: `Bearer ${process.env.BGL_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);
Python
import os
import requests
res = requests.get(
f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/link-health?filter=Failing",
headers={
"Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
},
timeout=30,
)
res.raise_for_status()
print(res.json())
Response
200 OK · application/json
JSON
{
"items": [
{
"linkId": "ZiZihoWXe3as",
"shortUrl": "https://bgum.me/spring-sale",
"title": "Spring sale",
"destinationUrl": "https://example.com/spring-sale",
"status": "Broken",
"confirming": false,
"ignored": false,
"lastResult": "Broken",
"httpStatus": 404,
"detail": "Page not found (HTTP 404).",
"finalUrl": null,
"redirects": 0,
"checkedAt": "2026-10-15T03:12:09.5170214+00:00",
"nextCheckAt": "2026-10-16T03:40:09.5170214+00:00",
"failingSince": "2026-10-15T02:11:47.0431987+00:00",
"humanClicks30Days": 431,
"history": null,
"failing": true
}
],
"page": 1,
"pageSize": 25,
"total": 1
}
Good to know
- confirming is true when the latest check failed but the one before didn't. The link is checked again within the hour, and only then shows as failing.
- humanClicks30Days counts clicks from people in the last 30 days, so you can fix the busiest links first.
- Paused, scheduled, expired, archived and disabled links aren't checked; they show as NotChecked.
Errors
Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.
Get a link's health
GET /links/{linkId}/health
Returns the link's destination health with its last 20 checks.
- Full path
/api/v1/workspaces/{workspaceId}/links/{linkId}/health- API key scope
-
links:read - Role needed
- Viewer or above
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspaceId |
string | Yes | Your workspace ID, from Settings → Workspace. |
linkId |
string | Yes | The link's ID, as returned when it was created or listed. |
Example request
curl
curl "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/links/ZiZihoWXe3as/health" \
-H "Authorization: Bearer $BGL_API_KEY"
JavaScript
const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/links/ZiZihoWXe3as/health`, {
headers: {
Authorization: `Bearer ${process.env.BGL_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);
Python
import os
import requests
res = requests.get(
f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/links/ZiZihoWXe3as/health",
headers={
"Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
},
timeout=30,
)
res.raise_for_status()
print(res.json())
Response
200 OK · application/json
JSON
{
"linkId": "ZiZihoWXe3as",
"shortUrl": "https://bgum.me/spring-sale",
"title": "Spring sale",
"destinationUrl": "https://example.com/spring-sale",
"status": "Broken",
"confirming": false,
"ignored": false,
"lastResult": "Broken",
"httpStatus": 404,
"detail": "Page not found (HTTP 404).",
"finalUrl": null,
"redirects": 0,
"checkedAt": "2026-10-15T03:12:09.5170214+00:00",
"nextCheckAt": "2026-10-16T03:40:09.5170214+00:00",
"failingSince": "2026-10-15T02:11:47.0431987+00:00",
"humanClicks30Days": 431,
"history": [
{
"checkedAt": "2026-10-15T03:12:09.5170214+00:00",
"result": "Broken",
"httpStatus": 404,
"detail": "Page not found (HTTP 404).",
"manual": false
},
{
"checkedAt": "2026-10-15T02:11:47.0431987+00:00",
"result": "Broken",
"httpStatus": 404,
"detail": "Page not found (HTTP 404).",
"manual": false
}
],
"failing": true
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 404 | link.not_found | No link with that ID in this workspace (or it was deleted). |
Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.
Check a link now
POST /links/{linkId}/health/check
Checks the link's destination straight away and returns the result, for example after you've fixed the page.
- Full path
/api/v1/workspaces/{workspaceId}/links/{linkId}/health/check- API key scope
-
links:write - Role needed
- Manager or above
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspaceId |
string | Yes | Your workspace ID, from Settings → Workspace. |
linkId |
string | Yes | The link's ID, as returned when it was created or listed. |
Example request
curl
curl -X POST "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/links/ZiZihoWXe3as/health/check" \
-H "Authorization: Bearer $BGL_API_KEY"
JavaScript
const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/links/ZiZihoWXe3as/health/check`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BGL_API_KEY}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);
Python
import os
import requests
res = requests.post(
f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/links/ZiZihoWXe3as/health/check",
headers={
"Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
},
timeout=30,
)
res.raise_for_status()
print(res.json())
Response
200 OK · application/json
JSON
{
"linkId": "ZiZihoWXe3as",
"shortUrl": "https://bgum.me/spring-sale",
"title": "Spring sale",
"destinationUrl": "https://example.com/spring-sale",
"status": "Working",
"confirming": false,
"ignored": false,
"lastResult": "Working",
"httpStatus": 200,
"detail": "Works.",
"finalUrl": null,
"redirects": 0,
"checkedAt": "2026-10-15T03:12:09.5170214+00:00",
"nextCheckAt": "2026-10-16T03:40:09.5170214+00:00",
"failingSince": null,
"humanClicks30Days": 431,
"history": null,
"failing": false
}
Good to know
- Each link can be checked by hand once a minute, and a workspace up to 30 times an hour.
- A failed check by hand counts like any other: the link shows as failing once two checks in a row fail.
Errors
| Status | Code | Meaning |
|---|---|---|
| 404 | link.not_found | No link with that ID in this workspace (or it was deleted). |
| 409 | link_health.not_checkable | The link isn't live (it's paused, scheduled, expired, archived or disabled), so it isn't checked. |
| 429 | link_health.too_soon | The link was checked by hand less than a minute ago, or the workspace has checked 30 links by hand in the last hour. |
| 409 | link_health.off | Link checks are switched off on this service. |
Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.
Ignore a link
PUT /links/{linkId}/health/ignored
Stops checking and reporting a link, for example a site that refuses automated checks but works for people. Send false to start again.
- Full path
/api/v1/workspaces/{workspaceId}/links/{linkId}/health/ignored- API key scope
-
links:write - Role needed
- Manager or above
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspaceId |
string | Yes | Your workspace ID, from Settings → Workspace. |
linkId |
string | Yes | The link's ID, as returned when it was created or listed. |
Request body
JSON (Content-Type: application/json). Leave out fields you don't need.
| Name | Type | Required | Description |
|---|---|---|---|
ignored |
boolean | Yes | true stops the checks, false starts them again. |
Example request
curl
curl -X PUT "https://bgum.me/api/v1/workspaces/$WORKSPACE_ID/links/ZiZihoWXe3as/health/ignored" \
-H "Authorization: Bearer $BGL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ignored": true
}'
JavaScript
const res = await fetch(`https://bgum.me/api/v1/workspaces/${process.env.WORKSPACE_ID}/links/ZiZihoWXe3as/health/ignored`, {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.BGL_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"ignored": true
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);
Python
import os
import requests
res = requests.put(
f"https://bgum.me/api/v1/workspaces/{os.environ['WORKSPACE_ID']}/links/ZiZihoWXe3as/health/ignored",
headers={
"Authorization": f"Bearer {os.environ['BGL_API_KEY']}",
},
json={
"ignored": True,
},
timeout=30,
)
res.raise_for_status()
print(res.json())
Response
200 OK · application/json
JSON
{
"linkId": "ZiZihoWXe3as",
"shortUrl": "https://bgum.me/spring-sale",
"title": "Spring sale",
"destinationUrl": "https://example.com/spring-sale",
"status": "Broken",
"confirming": false,
"ignored": true,
"lastResult": "Broken",
"httpStatus": 404,
"detail": "Page not found (HTTP 404).",
"finalUrl": null,
"redirects": 0,
"checkedAt": "2026-10-15T03:12:09.5170214+00:00",
"nextCheckAt": null,
"failingSince": "2026-10-15T02:11:47.0431987+00:00",
"humanClicks30Days": 431,
"history": null,
"failing": true
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 404 | link.not_found | No link with that ID in this workspace (or it was deleted). |
Any request can also return the general errors: 401 for a missing or wrong key, 403 for a missing scope or plan feature, 404 for an unknown workspace and 429 when you're sending too fast.
Something missing or unclear? Tell us and we'll improve this page.