Skip to main content

Overview

Services represent applications or databases exposed by agents. The Services API provides endpoints for registration, health monitoring, diagnostics, and public URL management.

Register Service

Register a new service exposed by an agent.
curl -X POST https://api.privateconnect.co/v1/services/register \
  -H "x-api-key: pc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "name": "prod-db",
    "targetHost": "localhost",
    "targetPort": 5432,
    "protocol": "tcp",
    "isPublic": false
  }'
Request Body:
agentId
string
required
UUID of the agent exposing this service
name
string
required
Service name (1-100 characters, alphanumeric, hyphens, underscores)
targetHost
string
required
Target hostname (e.g., localhost, 127.0.0.1). Max 253 characters.
targetPort
number
required
Target port number (1-65535)
protocol
string
default:"auto"
Protocol: auto, tcp, udp, http, https
isPublic
boolean
default:"false"
Make publicly accessible via generated URL
Response:
{
  "success": true,
  "service": {
    "id": "svc_123",
    "name": "prod-db",
    "tunnelPort": 50123,
    "status": "active",
    "protocol": "tcp",
    "isPublic": false,
    "publicUrl": null
  }
}
tunnelPort
number
Port on the hub where the service is accessible via tunnel

Create External Service

Register an external service target (not exposed by an agent). Useful for monitoring external APIs or databases.
curl -X POST https://api.privateconnect.co/v1/services/external \
  -H "x-api-key: pc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "external-api",
    "targetHost": "api.example.com",
    "targetPort": 443,
    "protocol": "https"
  }'
Request Body:
name
string
required
Service name
targetHost
string
required
External hostname or IP
targetPort
number
required
External port
protocol
string
default:"auto"
Protocol: auto, tcp, udp, http, https
Response:
{
  "success": true,
  "service": {
    "id": "svc_456",
    "name": "external-api",
    "targetHost": "api.example.com",
    "targetPort": 443,
    "protocol": "https",
    "isExternal": true
  }
}
An initial health check runs automatically when creating an external service.

List Services

Retrieve all services in the workspace.
curl https://api.privateconnect.co/v1/services \
  -H "x-api-key: pc_your_api_key"
Response:
[
  {
    "id": "svc_123",
    "name": "prod-db",
    "agentId": "550e8400-e29b-41d4-a716-446655440000",
    "targetHost": "localhost",
    "targetPort": 5432,
    "tunnelPort": 50123,
    "protocol": "tcp",
    "status": "active",
    "isPublic": false,
    "isExternal": false,
    "lastCheckAt": "2026-03-02T10:00:00.000Z",
    "createdAt": "2026-03-01T10:00:00.000Z"
  }
]

Get Service Details

Retrieve details for a specific service.
curl https://api.privateconnect.co/v1/services/svc_123 \
  -H "x-api-key: pc_your_api_key"
Response:
{
  "id": "svc_123",
  "name": "prod-db",
  "agentId": "550e8400-e29b-41d4-a716-446655440000",
  "targetHost": "localhost",
  "targetPort": 5432,
  "tunnelPort": 50123,
  "protocol": "tcp",
  "status": "active",
  "isPublic": false,
  "publicSubdomain": null,
  "publicUrl": null,
  "lastCheckAt": "2026-03-02T10:00:00.000Z",
  "lastCheckStatus": "OK",
  "createdAt": "2026-03-01T10:00:00.000Z"
}

Update Service

Update service properties like name.
curl -X PATCH https://api.privateconnect.co/v1/services/svc_123 \
  -H "x-api-key: pc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production-database"
  }'
Request Body:
name
string
New service name (1-100 characters, alphanumeric, hyphens, underscores)
Response:
{
  "success": true,
  "service": {
    "id": "svc_123",
    "name": "production-database"
  }
}

Delete Service

Delete a service from the workspace.
curl -X DELETE https://api.privateconnect.co/v1/services/svc_123 \
  -H "x-api-key: pc_your_api_key"
Response:
{
  "success": true
}

Diagnostics

Run Service Check

Run a diagnostic check on a service to verify connectivity and health.
curl -X POST https://api.privateconnect.co/v1/services/svc_123/check \
  -H "x-api-key: pc_your_api_key"
Response:
{
  "success": true,
  "diagnostic": {
    "id": "diag_123",
    "serviceId": "svc_123",
    "tcpStatus": "OK",
    "tcpLatencyMs": 12,
    "tlsStatus": "N/A",
    "httpStatus": "N/A",
    "perspective": "hub",
    "timestamp": "2026-03-02T10:00:00.000Z"
  },
  "service": {
    "id": "svc_123",
    "status": "active",
    "lastCheckAt": "2026-03-02T10:00:00.000Z"
  }
}
diagnostic.perspective
string
Diagnostic perspective: hub (from control plane) or agent (from specific agent)

Get Diagnostic History

Retrieve diagnostic history for a service.
curl "https://api.privateconnect.co/v1/services/svc_123/diagnostics?limit=50" \
  -H "x-api-key: pc_your_api_key"
Query Parameters:
limit
number
default:"50"
Limit number of results
Response:
[
  {
    "id": "diag_123",
    "serviceId": "svc_123",
    "tcpStatus": "OK",
    "tcpLatencyMs": 12,
    "tlsStatus": "N/A",
    "httpStatus": "OK",
    "httpStatusCode": 200,
    "httpLatencyMs": 45,
    "perspective": "hub",
    "sourceAgent": null,
    "timestamp": "2026-03-02T10:00:00.000Z"
  }
]

Reach Check

Test connectivity to a service from a specific agent (agent perspective diagnostics).
curl -X POST https://api.privateconnect.co/v1/services/svc_123/reach \
  -H "x-api-key: pc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceAgentId": "550e8400-e29b-41d4-a716-446655440000",
    "mode": "tcp",
    "timeoutMs": 5000
  }'
Request Body:
sourceAgentId
string
required
UUID of the agent to test connectivity from
mode
string
default:"tcp"
Test mode: tcp, tls, http
timeoutMs
number
default:"5000"
Timeout in milliseconds (1000-30000)
Response:
{
  "success": true,
  "diagnostic": {
    "id": "diag_124",
    "perspective": "agent",
    "sourceAgent": "web-server-1",
    "tcpStatus": "OK",
    "tcpLatencyMs": 8
  },
  "session": {
    "id": "sess_123",
    "outcome": "success"
  }
}
Reach checks create diagnostic sessions for tracking agent-to-service connectivity patterns.

Public Access

Set Custom Subdomain

Set a custom vanity subdomain for public access to a service.
curl -X PATCH https://api.privateconnect.co/v1/services/svc_123/subdomain \
  -H "x-api-key: pc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "subdomain": "my-staging-api"
  }'
Request Body:
subdomain
string
Custom subdomain (3-32 characters, lowercase alphanumeric and hyphens). Set to null to clear.
Response:
{
  "success": true,
  "service": {
    "id": "svc_123",
    "publicSubdomain": "pc-my-staging-api",
    "isPublic": true,
    "publicUrl": "https://pc-my-staging-api.privateconnect.co"
  }
}
Subdomains are automatically prefixed with pc- to prevent conflicts. The service must have isPublic: true.

Check Subdomain Availability

Check if a subdomain is available and valid.
curl "https://api.privateconnect.co/v1/services/svc_123/subdomain/check?subdomain=my-staging-api" \
  -H "x-api-key: pc_your_api_key"
Query Parameters:
subdomain
string
required
Subdomain to check
Response:
{
  "available": true,
  "valid": true,
  "subdomain": "pc-my-staging-api",
  "publicUrl": "https://pc-my-staging-api.privateconnect.co"
}
If unavailable or invalid:
{
  "available": false,
  "valid": true,
  "error": "Subdomain is already taken"
}

Protocol Detection

The protocol field supports auto-detection:
Automatically detect protocol based on port:
  • Port 80, 8080, 3000, 5000 → http
  • Port 443, 8443 → https
  • Port 5432 → PostgreSQL (tcp)
  • Port 3306 → MySQL (tcp)
  • Port 27017 → MongoDB (tcp)
  • Port 6379 → Redis (tcp)
  • All other ports → tcp
Raw TCP connection. Works for databases, custom protocols, and any TCP service.
UDP protocol. For services like DNS, VoIP, game servers.
HTTP protocol. Enables HTTP-specific diagnostics like status code checking.
HTTPS protocol with TLS. Validates certificates and enables secure proxying.

Service Status

Services have the following status values:
  • active - Service is running and accessible
  • inactive - Service is registered but not currently accessible
  • error - Service encountered an error during last health check
  • unknown - Service status has not been checked yet

Best Practices

Health Monitoring

Run periodic diagnostic checks to monitor service health. Set up webhooks to receive alerts when services go down.

Public Services

Only make services public when necessary. Use shares with access control for temporary external access.

Naming Convention

Use descriptive names like prod-api, staging-db, dev-redis to easily identify services.

External Services

Use external services to monitor third-party APIs and databases that aren’t behind agents.

Build docs developers (and LLMs) love