DonutworkHelp Center
Api ReferenceSistemi e monitoraggio
Documentazione Donutwork

TLS Monitor

Register HTTPS endpoints, inspect certificate health, and queue on-demand TLS scans.

TLS Monitor API

TLS Monitor tracks HTTPS certificate health for company-owned monitor records. Creating a monitor queues its first scan. Changing the hostname clears the previous result and queues another scan; an accepted scan is asynchronous and does not mean the certificate was healthy.

List monitors

GET
/2026-02-01/systems/tls-monitor.json
Required permissiontls_monitor:read

Path, query, and header parameters

pageinteger· query
Page number starting at 1. Default: 1.
sizeinteger· query
Records per page from 1 to 100. Default: 100.
hostnamestring· query
Exact configured HTTPS URL filter.
tagstring· query
Return monitors containing this tag.
statusenum· query
success, warning, error, or pending.

Responses

Paginated monitor summaries.

{
  "entities": "TlsMonitor",
  "count": 1,
  "per_page": 100,
  "pages": {
    "current": 1,
    "max": 1
  },
  "elements": [
    {
      "id": "MONITOR_ID",
      "name": "Customer portal",
      "hostname": "https://portal.example.com",
      "status": "success",
      "tags": [
        "production"
      ],
      "last_check": 1789722000,
      "certificate_type": "domain_validated",
      "validation_type": "DV",
      "expires_at": 1794902400
    }
  ]
}

Request examples

curl --request GET 'https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor.json', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Create a monitor

POST
/2026-02-01/systems/tls-monitor.json
Required permissiontls_monitor:write

Path, query, and header parameters

No path, query, or additional header parameters.

Request Body

JSON
{
  "tlsMonitor": {
    "name": "Customer portal",
    "hostname": "https://portal.example.com",
    "tags": [
      "production",
      "customer-facing"
    ],
    "notificationTo": [
      "ops@example.com"
    ]
  }
}
tlsMonitor.namestringRequired
Non-empty monitor name.
tlsMonitor.hostnameHTTPS URLRequired
Public HTTPS target validated by the outbound URL security policy.
tlsMonitor.tagsstring[]
Classification tags; a comma-separated string is also accepted.
tlsMonitor.notificationTostring[]
Notification recipients; notification_to is accepted as an alias.

Responses

Monitor created and initial scan queued when available.

{
  "tlsMonitor": {
    "id": "MONITOR_ID",
    "name": "Customer portal",
    "hostname": "https://portal.example.com"
  },
  "scanQueued": true
}

Name or HTTPS target is invalid.

{
  "error": "A valid hostname (https://...) must be specified"
}

Request examples

curl --request POST 'https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor.json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "tlsMonitor": {
    "name": "Customer portal",
    "hostname": "https://portal.example.com",
    "tags": [
      "production",
      "customer-facing"
    ],
    "notificationTo": [
      "ops@example.com"
    ]
  }
}'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor.json', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "tlsMonitor": {
      "name": "Customer portal",
      "hostname": "https://portal.example.com",
      "tags": [
        "production",
        "customer-facing"
      ],
      "notificationTo": [
        "ops@example.com"
      ]
    }
  }),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{
  "tlsMonitor": {
    "name": "Customer portal",
    "hostname": "https://portal.example.com",
    "tags": [
      "production",
      "customer-facing"
    ],
    "notificationTo": [
      "ops@example.com"
    ]
  }
}',
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Retrieve a monitor

GET
/2026-02-01/systems/tls-monitor/{tlsMonitorId}.json
Required permissiontls_monitor:read

Path, query, and header parameters

tlsMonitorIdstring· pathRequired
Company-scoped TLS monitor ID.

Responses

Full monitor configuration and most recent response.

{
  "id": "MONITOR_ID",
  "name": "Customer portal",
  "hostname": "https://portal.example.com",
  "tags": [
    "production"
  ],
  "last_response": {
    "status": "success"
  }
}

Monitor not found in this company.

{
  "error": "Tls monitor not found"
}

Request examples

curl --request GET 'https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json', {
  method: 'GET',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Update a monitor

PUT
/2026-02-01/systems/tls-monitor/{tlsMonitorId}.json
Required permissiontls_monitor:write

Path, query, and header parameters

tlsMonitorIdstring· pathRequired
Company-scoped TLS monitor ID.

Request Body

JSON
{
  "tlsMonitor": {
    "name": "Customer portal EU",
    "hostname": "https://eu.portal.example.com",
    "tags": [
      "production",
      "eu"
    ],
    "notificationTo": [
      "ops@example.com"
    ]
  }
}
tlsMonitor.namestring
Replacement non-empty name.
tlsMonitor.hostnameHTTPS URL
Replacement target. A change clears the previous result and queues a scan.
tlsMonitor.tagsstring[]
Complete replacement tag list.
tlsMonitor.notificationTostring[]
Complete replacement recipient list; notification_to is accepted as an alias.

Responses

Monitor updated.

{
  "tlsMonitor": {
    "id": "MONITOR_ID",
    "hostname": "https://eu.portal.example.com"
  },
  "scanQueued": true
}

Monitor not found in this company.

{
  "error": "Tls monitor not found"
}

Request examples

curl --request PUT 'https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "tlsMonitor": {
    "name": "Customer portal EU",
    "hostname": "https://eu.portal.example.com",
    "tags": [
      "production",
      "eu"
    ],
    "notificationTo": [
      "ops@example.com"
    ]
  }
}'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "tlsMonitor": {
      "name": "Customer portal EU",
      "hostname": "https://eu.portal.example.com",
      "tags": [
        "production",
        "eu"
      ],
      "notificationTo": [
        "ops@example.com"
      ]
    }
  }),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => '{
  "tlsMonitor": {
    "name": "Customer portal EU",
    "hostname": "https://eu.portal.example.com",
    "tags": [
      "production",
      "eu"
    ],
    "notificationTo": [
      "ops@example.com"
    ]
  }
}',
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Delete a monitor

DELETE
/2026-02-01/systems/tls-monitor/{tlsMonitorId}.json
Required permissiontls_monitor:write

Path, query, and header parameters

tlsMonitorIdstring· pathRequired
Company-scoped TLS monitor ID.

Responses

Monitor deleted.

{
  "id": "MONITOR_ID",
  "deleted": true
}

Monitor not found in this company.

{
  "error": "Tls monitor not found"
}

Request examples

curl --request DELETE 'https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json', {
  method: 'DELETE',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

Queue an on-demand scan

POST
/2026-02-01/systems/tls-monitor/{tlsMonitorId}/scan.json
Required permissiontls_monitor:write

Path, query, and header parameters

tlsMonitorIdstring· pathRequired
Company-scoped TLS monitor ID.

Responses

Scan command queued; poll the monitor for the resulting status.

{
  "id": "MONITOR_ID",
  "scanQueued": true
}

Monitor not found in this company.

{
  "error": "Tls monitor not found"
}

The command could not be queued.

{
  "error": "Unable to enqueue tls scan now"
}

Request examples

curl --request POST 'https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID/scan.json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID/scan.json', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
  },
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
  const error = await response.text();
  throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
  : contentType.includes('application/json') ? await response.json()
  : await response.text();
$request = curl_init('https://api.hub.donutwork.com/2026-02-01/systems/tls-monitor/TLSMONITORID/scan.json');
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
    ],
]);
$response = curl_exec($request);
if ($response === false) {
    $error = curl_error($request);
    curl_close($request);
    throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
    : (str_contains($contentType, 'application/json')
        ? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);

Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.

On this page