TCP Monitors

Create and manage TCP monitors. Check port connectivity and get connection history.

TCP monitors verify that services are accepting connections on specific ports. Use them to monitor databases, mail servers, game servers, and any TCP-based service.

List All TCP Monitors

GET/api/v1/tcp-monitors

Retrieve your team's TCP monitors, newest first.

This endpoint is paginated. See Pagination for how to page through the full list.

Required scope: tcp-monitors:read

Query Parameters

  • perPageinteger

    Results per page, 1-200 (default: 50)

  • cursorstring

    Page to fetch, taken from a Link header

Errors (3)
StatusTypeMeaning
400bad-requestThe request is malformed
401unauthorizedThe API key is missing or invalid
403forbiddenThe API key lacks the required scope
Response fields (200)
  • dataobjectRequired
    Show nested fields
    • monitorsTcpMonitor[]Required
      Show nested fields
      • idstringRequired
      • namestringRequired
      • hoststringRequired
      • portintegerRequired
      • timeoutMsintegerRequired
      • intervalSecondsintegerRequired
      • isEnabledbooleanRequired
      • lastCheckedAtinteger | nullRequired

        Epoch milliseconds

      • lastStatusstring | nullRequired

        One of up, down, timeout.

      • lastResponseTimeMsinteger | nullRequired
      • createdAtintegerRequired

        Epoch milliseconds

      • updatedAtintegerRequired

        Epoch milliseconds

  • metaobjectRequired
    Show nested fields
    • requestIdstringRequired

      Format: uuid.

    • timestampstringRequired

      Format: date-time.

    • paginationobjectRequired
      Show nested fields
      • nextstring | nullRequired

        Cursor of the following page

      • prevstring | nullRequired

        Cursor of the preceding page

      • perPageintegerRequired
      • totalinteger
Terminal
curl -i "https://uptime.sergiodxa.com/api/v1/tcp-monitors?perPage=25" \
  -H "Authorization: Bearer uptime_your_api_key"

Response

json
{
	"data": {
		"monitors": [
			{
				"id": "tcpm_abc123",
				"name": "PostgreSQL Production",
				"host": "db.example.com",
				"port": 5432,
				"timeoutMs": 5000,
				"intervalSeconds": 60,
				"isEnabled": true,
				"lastCheckedAt": 1771070400000,
				"lastStatus": "up",
				"lastResponseTimeMs": 45,
				"createdAt": 1768473000000,
				"updatedAt": 1770733200000
			}
		]
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z",
		"pagination": {
			"next": "eyJkIjoiYWZ0ZXIi",
			"prev": null,
			"perPage": 25,
			"total": 34
		}
	}
}

Create a TCP Monitor

POST/api/v1/tcp-monitors

Create a new TCP monitor to check port connectivity.

Required scope: tcp-monitors:write

Request Body

  • namestringRequired

    Monitor name (1-255 characters)

  • hoststringRequired

    Hostname or IP address (1-255 characters)

  • portintegerRequired

    TCP port number (1-65535)

  • timeoutMsinteger

    Connection timeout in milliseconds (100-60000, default: 5000)

  • intervalSecondsinteger

    Check interval in seconds (60-86400, default: 60)

  • isEnabledboolean

    Whether the monitor is active (default: true)

Errors (6)
StatusTypeMeaning
400validation-errorThe request failed validation
400idempotency-key-invalidThe Idempotency-Key header is not valid
401unauthorizedThe API key is missing or invalid
403forbiddenThe API key lacks the required scope
409idempotency-key-in-useA request with this idempotency key is still being processed
422idempotency-key-reusedThis idempotency key was already used for a different request
Response fields (201)
  • dataobjectRequired
    Show nested fields
    • monitorobjectRequired
      Show nested fields
      • idstringRequired
      • namestringRequired
      • hoststringRequired
      • portintegerRequired
      • timeoutMsintegerRequired
      • intervalSecondsintegerRequired
      • isEnabledbooleanRequired
      • lastCheckedAtinteger | nullRequired

        Epoch milliseconds

      • lastStatusstring | nullRequired

        One of up, down, timeout.

      • lastResponseTimeMsinteger | nullRequired
      • createdAtintegerRequired

        Epoch milliseconds

      • updatedAtintegerRequired

        Epoch milliseconds

  • metaobjectRequired
    Show nested fields
    • requestIdstringRequired

      Format: uuid.

    • timestampstringRequired

      Format: date-time.

Terminal
curl https://uptime.sergiodxa.com/api/v1/tcp-monitors \
  -H "Authorization: Bearer uptime_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "PostgreSQL Production",
    "host": "db.example.com",
    "port": 5432,
    "timeoutMs": 10000,
    "intervalSeconds": 60
  }'
request.js
let response = await fetch("https://uptime.sergiodxa.com/api/v1/tcp-monitors", {
	method: "POST",
	headers: {
		"Authorization": "Bearer uptime_your_api_key",
		"Content-Type": "application/json",
	},
	body: JSON.stringify({
		"name": "PostgreSQL Production",
		"host": "db.example.com",
		"port": 5432,
		"timeoutMs": 10000,
		"intervalSeconds": 60
	}),
});
let result = await response.json();

Response

json
{
	"data": {
		"monitor": {
			"id": "tcpm_abc123",
			"name": "PostgreSQL Production",
			"host": "db.example.com",
			"port": 5432,
			"timeoutMs": 10000,
			"intervalSeconds": 60,
			"isEnabled": true,
			"lastCheckedAt": null,
			"lastStatus": null,
			"lastResponseTimeMs": null,
			"createdAt": 1771070400000,
			"updatedAt": 1771070400000
		}
	}
}

Get a TCP Monitor

GET/api/v1/tcp-monitors/:id

Retrieve a single TCP monitor by ID.

Required scope: tcp-monitors:read

Errors (4)
StatusTypeMeaning
400validation-errorThe request failed validation
401unauthorizedThe API key is missing or invalid
403forbiddenThe API key lacks the required scope
404not-foundThe resource does not exist
Response fields (200)
  • dataobjectRequired
    Show nested fields
    • monitorobjectRequired
      Show nested fields
      • idstringRequired
      • namestringRequired
      • hoststringRequired
      • portintegerRequired
      • timeoutMsintegerRequired
      • intervalSecondsintegerRequired
      • isEnabledbooleanRequired
      • lastCheckedAtinteger | nullRequired

        Epoch milliseconds

      • lastStatusstring | nullRequired

        One of up, down, timeout.

      • lastResponseTimeMsinteger | nullRequired
      • createdAtintegerRequired

        Epoch milliseconds

      • updatedAtintegerRequired

        Epoch milliseconds

  • metaobjectRequired
    Show nested fields
    • requestIdstringRequired

      Format: uuid.

    • timestampstringRequired

      Format: date-time.

Terminal
curl https://uptime.sergiodxa.com/api/v1/tcp-monitors/tcpm_abc123 \
  -H "Authorization: Bearer uptime_your_api_key"
request.js
let response = await fetch("https://uptime.sergiodxa.com/api/v1/tcp-monitors/tcpm_abc123", {
	headers: {
		"Authorization": "Bearer uptime_your_api_key",
	},
});
let result = await response.json();

Response

json
{
	"data": {
		"monitor": {
			"id": "tcpm_abc123",
			"name": "PostgreSQL Production",
			"host": "db.example.com",
			"port": 5432,
			"timeoutMs": 5000,
			"intervalSeconds": 60,
			"isEnabled": true,
			"lastCheckedAt": 1771070400000,
			"lastStatus": "up",
			"lastResponseTimeMs": 45,
			"createdAt": 1768473000000,
			"updatedAt": 1770733200000
		}
	}
}

Update a TCP Monitor

PATCH/api/v1/tcp-monitors/:id

Update an existing TCP monitor with a JSON merge patch. Only include fields you want to change.

Required scope: tcp-monitors:write

Request Body

  • namestring

    Monitor name (1-255 characters)

  • hoststring

    Hostname or IP address (1-255 characters)

  • portinteger

    TCP port number (1-65535)

  • timeoutMsinteger

    Connection timeout in milliseconds (100-60000)

  • intervalSecondsinteger

    Check interval in seconds (60-86400)

  • isEnabledboolean

    Whether the monitor is active

The limits are the ones Create a TCP Monitor applies. null resets timeoutMs to 5000, intervalSeconds to 60 and isEnabled to true; name, host and port cannot be removed, so null on any of them is a 400 validation-error.

Update With PUT

PUT /api/v1/tcp-monitors/:id takes the same fields, for integrations written before PATCH existed. A field you leave out keeps its value, null is refused, and sending isEnabled schedules the next check again on every request, even when the value is unchanged.

Required scope: tcp-monitors:write

Errors (4)
StatusTypeMeaning
400validation-errorThe request failed validation
401unauthorizedThe API key is missing or invalid
403forbiddenThe API key lacks the required scope
404not-foundThe resource does not exist
Response fields (200)
  • dataobjectRequired
    Show nested fields
    • monitorobjectRequired
      Show nested fields
      • idstringRequired
      • namestringRequired
      • hoststringRequired
      • portintegerRequired
      • timeoutMsintegerRequired
      • intervalSecondsintegerRequired
      • isEnabledbooleanRequired
      • lastCheckedAtinteger | nullRequired

        Epoch milliseconds

      • lastStatusstring | nullRequired

        One of up, down, timeout.

      • lastResponseTimeMsinteger | nullRequired
      • createdAtintegerRequired

        Epoch milliseconds

      • updatedAtintegerRequired

        Epoch milliseconds

  • metaobjectRequired
    Show nested fields
    • requestIdstringRequired

      Format: uuid.

    • timestampstringRequired

      Format: date-time.

Terminal
curl https://uptime.sergiodxa.com/api/v1/tcp-monitors/tcpm_abc123 \
  -X PATCH \
  -H "Authorization: Bearer uptime_your_api_key" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
    "timeoutMs": 15000,
    "isEnabled": false
  }'
request.js
let response = await fetch("https://uptime.sergiodxa.com/api/v1/tcp-monitors/tcpm_abc123", {
	method: "PATCH",
	headers: {
		"Authorization": "Bearer uptime_your_api_key",
		"Content-Type": "application/merge-patch+json",
	},
	body: JSON.stringify({
		"timeoutMs": 15000,
		"isEnabled": false
	}),
});
let result = await response.json();

Response

json
{
	"data": {
		"monitor": {
			"id": "tcpm_abc123",
			"name": "PostgreSQL Production",
			"host": "db.example.com",
			"port": 5432,
			"timeoutMs": 15000,
			"intervalSeconds": 60,
			"isEnabled": false,
			"lastCheckedAt": 1771070400000,
			"lastStatus": "up",
			"lastResponseTimeMs": 45,
			"createdAt": 1768473000000,
			"updatedAt": 1771072200000
		}
	}
}

Delete a TCP Monitor

DELETE/api/v1/tcp-monitors/:id

Permanently delete a TCP monitor and all its check history.

Required scope: tcp-monitors:delete

Errors (4)
StatusTypeMeaning
400validation-errorThe request failed validation
401unauthorizedThe API key is missing or invalid
403forbiddenThe API key lacks the required scope
404not-foundThe resource does not exist
Response fields (200)
  • dataobjectRequired
    Show nested fields
    • deletedtrueRequired
  • metaobjectRequired
    Show nested fields
    • requestIdstringRequired

      Format: uuid.

    • timestampstringRequired

      Format: date-time.

Terminal
curl https://uptime.sergiodxa.com/api/v1/tcp-monitors/tcpm_abc123 \
  -X DELETE \
  -H "Authorization: Bearer uptime_your_api_key"
request.js
let response = await fetch("https://uptime.sergiodxa.com/api/v1/tcp-monitors/tcpm_abc123", {
	method: "DELETE",
	headers: {
		"Authorization": "Bearer uptime_your_api_key",
	},
});
let result = await response.json();

Response

json
{ "data": { "deleted": true } }

Get Check Results

GET/api/v1/tcp-monitors/:id/results

Retrieve the connection check history for a TCP monitor.

Results arrive newest first, a page at a time. See Pagination for how to walk the whole history.

Required scope: tcp-monitors:read

Query Parameters

  • perPageinteger

    Results per page, 1-200 (default: 50)

  • cursorstring

    Page to fetch, taken from a Link header

Errors (5)
StatusTypeMeaning
400bad-requestThe request is malformed
400validation-errorThe request failed validation
401unauthorizedThe API key is missing or invalid
403forbiddenThe API key lacks the required scope
404not-foundThe resource does not exist
Response fields (200)
  • dataobjectRequired
    Show nested fields
    • resultsTcpMonitorResult[]Required
      Show nested fields
      • idstringRequired
      • statusstringRequired

        One of up, down, timeout.

      • responseTimeMsinteger | nullRequired
      • errorMessagestring | nullRequired
      • checkedAtintegerRequired

        Epoch milliseconds

  • metaobjectRequired
    Show nested fields
    • requestIdstringRequired

      Format: uuid.

    • timestampstringRequired

      Format: date-time.

    • paginationobjectRequired
      Show nested fields
      • nextstring | nullRequired

        Cursor of the following page

      • prevstring | nullRequired

        Cursor of the preceding page

      • perPageintegerRequired
      • totalinteger
Terminal
curl -i "https://uptime.sergiodxa.com/api/v1/tcp-monitors/tcpm_abc123/results?perPage=10" \
  -H "Authorization: Bearer uptime_your_api_key"

Response

json
{
	"data": {
		"results": [
			{
				"id": "tcpr_xyz789",
				"status": "up",
				"responseTimeMs": 42,
				"errorMessage": null,
				"checkedAt": 1771070400000
			},
			{
				"id": "tcpr_xyz788",
				"status": "up",
				"responseTimeMs": 38,
				"errorMessage": null,
				"checkedAt": 1771070340000
			},
			{
				"id": "tcpr_xyz787",
				"status": "down",
				"responseTimeMs": null,
				"errorMessage": "Connection refused",
				"checkedAt": 1771070280000
			}
		]
	},
	"meta": {
		"requestId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
		"timestamp": "2026-02-14T12:00:00.000Z",
		"pagination": {
			"next": "eyJkIjoiYWZ0ZXIi",
			"prev": null,
			"perPage": 10
		}
	}
}
Documentation