API Reference v1 ← Back to Fixpoint

Fixpoint API

REST API for RMM integrations, MSP automation, and IT tooling. Base URL: https://fixpoint-3.polsia.app/api

Authentication

All integration endpoints require an API key passed via the X-API-Key header.

Request Header
X-API-Key: fp_live_your_key_here

Generate and manage API keys from your Fixpoint account. Keys are 256-bit random strings, SHA-256 hashed before storage — only the hash is retained.

Base URL https://fixpoint-3.polsia.app/api

Rate Limits

1,000 requests / hour per org
100 requests / min per org
20 POST /services / min
5 POST /services/:id/trigger-scan / min
Rate limit headers are returned on every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Services

GET /services List all monitored services

Returns all monitored Windows services for your organization, sorted by last_checked desc.

curl
curl -H "X-API-Key: fp_live_..." https://fixpoint-3.polsia.app/api/services
Response 200
{
  "services": [
    {
      "id": 12,
      "vm_host": "WIN-SRV-01.corp.internal",
      "service_name": "W3SVC",
      "last_known_state": "Running",
      "status": "ok",
      "last_checked": "2026-06-07T18:00:00Z"
    }
  ]
}
POST /services Register a service to monitor

Registers a Windows service for drift monitoring. Performs an immediate check — if the service is not Running, drift is flagged immediately.

FieldTypeDescription
vm_hoststringrequiredTarget Windows VM hostname or IP address
service_namestringrequiredWindows service name — e.g. W3SVC, Spooler, WSearch
last_known_statestringSkip initial check — set the known-good state (e.g. "Running")
curl
curl -X POST https://fixpoint-3.polsia.app/api/services \n
  -H "Content-Type: application/json" \n
  -H "X-API-Key: fp_live_..." \n
  -d '{"vm_host":"WIN-SRV-02","service_name":"WSearch"}'
Response 201
{
  "service": {
    "id": 14,
    "vm_host": "WIN-SRV-02",
    "service_name": "WSearch",
    "status": "ok",
    "last_known_state": "Running"
  }
}
GET /services/:id Get service detail

Returns service detail enriched with the last drift event and last sandbox execution result.

curl
curl -H "X-API-Key: fp_live_..." https://fixpoint-3.polsia.app/api/services/12
Response 200
{
  "service": {
    "id": 12,
    "vm_host": "WIN-SRV-01",
    "service_name": "W3SVC",
    "status": "drift",
    "last_known_state": "Stopped",
    "last_drift": { "id": 5, "status": "pending" },
    "last_sandbox_attempt": { "id": 3, "result": "approved" }
  }
}
POST /services/:id/trigger-scan Trigger a drift scan

Manually trigger a drift check. If drifted, generates a PowerShell remediation script. Webhooks fire for drift.detected and script.generated.

curl
curl -X POST https://fixpoint-3.polsia.app/api/services/12/trigger-scan \n
  -H "X-API-Key: fp_live_..."
Response 200 — healthy
{
  "service_id": 12,
  "service_name": "W3SVC",
  "state": "Running",
  "isDrift": false,
  "message": "Service is healthy"
}
Response 200 — drift detected
{
  "service_id": 12,
  "service_name": "W3SVC",
  "state": "Stopped",
  "isDrift": true,
  "script": "Start-Service -Name 'W3SVC' ...",
  "message": "Drift detected — remediation script generated"
}

Drift Events

GET /drift-events List drift events

Returns drift events for your org, sorted by most recent first.

Query ParamTypeDescription
service_idintegerFilter by service ID
statusstringpending, remediating, resolved
start_datestringISO 8601 date filter — e.g. 2026-06-01
end_datestringISO 8601 date filter
limitintegerMax results — default 100, max 500
offsetintegerPagination offset
curl
curl -H "X-API-Key: fp_live_..." "https://fixpoint-3.polsia.app/api/drift-events?status=pending&limit=50"
Response 200
{
  "drift_events": [
    {
      "id": 5,
      "service_id": 12,
      "service_name": "W3SVC",
      "vm_host": "WIN-SRV-01",
      "detected_state": "Stopped",
      "drift_type": "service_stopped",
      "status": "pending",
      "remediation_script": "Start-Service -Name 'W3SVC' ...",
      "created_at": "2026-06-07T17:00:00Z"
    }
  ]
}

Sandbox Attempts

GET /sandbox-attempts List sandbox execution history

Returns script sandbox verification results — shows which scripts were approved, blocked, or errored before deployment.

Query ParamTypeDescription
service_idintegerFilter by service ID
resultstringapproved, blocked, error
limitintegerMax results — default 100, max 500
offsetintegerPagination offset
curl
curl -H "X-API-Key: fp_live_..." "https://fixpoint-3.polsia.app/api/sandbox-attempts?result=approved"
Response 200
{
  "sandbox_attempts": [
    {
      "id": 3,
      "service_id": 12,
      "service_name": "W3SVC",
      "vm_host": "WIN-SRV-01",
      "result": "approved",
      "duration_ms": 847,
      "exit_code": 0,
      "deployed": true,
      "created_at": "2026-06-07T16:55:00Z"
    }
  ]
}

Agent API

For endpoint agents running on remote Windows VMs. All endpoints require an agent key passed via Authorization: Bearer <agent_key> header.

Agent keys are scoped to a specific endpoint and org — an agent can only fetch services assigned to its own endpoint. Keys expire after 90 days of inactivity.

GET /api/agent/services?endpoint_id=<id> Get services for this endpoint

Returns all monitored services assigned to the calling endpoint, scoped to its org. Requires endpoint_id query param — must match the authenticated agent key.

curl
curl -H "Authorization: Bearer fp_agent_..." "https://fixpoint-3.polsia.app/api/agent/services?endpoint_id=WIN-SRV-01"
Response 200
{
  "services": [
    {
      "id": 12,
      "vm_host": "WIN-SRV-01",
      "service_name": "W3SVC",
      "last_known_state": "Running",
      "status": "ok"
    }
  ]
}
POST /api/agent/services/:id/status Update service status from endpoint

Reports current service state back to Fixpoint from the endpoint agent.

FieldTypeDescription
statusstringrequiredok | drift | remediating
curl
curl -X POST https://fixpoint-3.polsia.app/api/agent/services/12/status \n
  -H "Authorization: Bearer fp_agent_..." \n
  -H "Content-Type: application/json" \n
  -d '{"status":"ok"}'
Response 200
{ "service": { "id": 12, "status": "ok" } }
POST /api/agent/heartbeat Endpoint liveness ping

Sent periodically by the endpoint agent to confirm liveness. Also updates last_checked on all reported services.

FieldTypeDescription
endpoint_idstringMust match the authenticated agent key's endpoint
endpoint_ipstringCurrent IP of the endpoint (optional)
servicesarrayArray of {id, status} objects for quick status sync
curl
curl -X POST https://fixpoint-3.polsia.app/api/agent/heartbeat \n
  -H "Authorization: Bearer fp_agent_..." \n
  -H "Content-Type: application/json" \n
  -d '{"endpoint_id":"WIN-SRV-01","endpoint_ip":"10.0.0.5","services":[{"id":12,"status":"ok"}]}'
Response 200
{
  "received": true,
  "endpoint_id": "WIN-SRV-01",
  "timestamp": "2026-06-10T20:13:00Z"
}

Intune Proactive Remediations

Deploy PowerShell remediation scripts directly to Microsoft Intune. Requires Clerk JWT auth and an Azure AD tenant registered via POST /api/intune/tenants.

Tenant Setup

POST /api/intune/tenants Register Intune tenant credentials (Clerk auth)

Stores Azure AD app credentials for the org. Credentials are validated before saving. Requires Clerk Bearer token.

FieldTypeDescription
tenantIdstringrequiredAzure AD tenant (directory) ID
clientIdstringrequiredApp registration client ID
clientSecretstringrequiredApp registration client secret
displayNamestringLabel shown in Fixpoint — defaults to Tenant <id_prefix>
deviceGroupIdstringIntune device group ID for deployments
deviceGroupNamestringIntune device group name (alternative to deviceGroupId)
curl
curl -X POST https://fixpoint-3.polsia.app/api/intune/tenants \n
  -H "Authorization: Bearer <clerk_jwt>" \n
  -H "Content-Type: application/json" \n
  -d '{"tenantId":"abc123...","clientId":"def456...","clientSecret":"ghi789...","displayName":"Contoso Intune"}'
Response 200
{ "success": true, "tenantId": 1 }
GET /api/intune/tenants Get tenant config (Clerk auth)

Returns the current tenant configuration (client secret redacted). Requires Clerk Bearer token.

curl
curl -H "Authorization: Bearer <clerk_jwt>" https://fixpoint-3.polsia.app/api/intune/tenants
Response 200
{
  "id": 1,
  "tenant_id": "abc123...",
  "display_name": "Contoso Intune",
  "device_group_id": "gp-00001",
  "active": true
}
DELETE /api/intune/tenants Deactivate Intune tenant (Clerk auth)

Soft-deactivates the tenant — credentials are removed but deployment history is preserved. Requires Clerk Bearer token.

curl
curl -X DELETE -H "Authorization: Bearer <clerk_jwt>" https://fixpoint-3.polsia.app/api/intune/tenants
Response 200
{ "success": true }

Script Deployment

POST /api/intune/deploy Package and deploy script to Intune (Clerk auth)

Uploads a PowerShell remediation script to Intune Proactive Remediations as a script package. Scripts are base64-encoded as UTF-16LE (Intune requirement). Requires Clerk Bearer token.

FieldTypeDescription
displayNamestringrequiredDisplay name for the Intune script package
scriptContentstringrequiredRaw PowerShell remediation script (plain text)
serviceIdintegerFixpoint service ID — auto-generates detection script if omitted
detectionScriptstringOptional custom detection script (default: service-health check)
targetModestringscheduled (default) or on_demand
deviceGroupIdstringOverride tenant's default device group
curl
curl -X POST https://fixpoint-3.polsia.app/api/intune/deploy \n
  -H "Authorization: Bearer <clerk_jwt>" \n
  -H "Content-Type: application/json" \n
  -d '{"displayName":"Fix W3SVC drift","scriptContent":"Start-Service -Name \\"W3SVC\\"","serviceId":12}'
Response 201
{
  "success": true,
  "deployment": {
    "id": 5,
    "intuneScriptId": "proactive-remediation-abc123",
    "displayName": "Fix W3SVC drift",
    "status": "active",
    "targetMode": "scheduled"
  }
}

Deployments

GET /api/intune/deployments List all Intune deployments (Clerk auth)

Returns all script deployments for the org with run summary. Requires Clerk Bearer token.

curl
curl -H "Authorization: Bearer <clerk_jwt>" https://fixpoint-3.polsia.app/api/intune/deployments
Response 200
{
  "deployments": [
    {
      "id": 5,
      "displayName": "Fix W3SVC drift",
      "status": "active",
      "runSummary": { "pass": 42, "fail": 2, "unknown": 0 },
      "lastRunAt": "2026-06-10T18:00:00Z"
    }
  ]
}
GET /api/intune/deployments/:id Deployment detail with per-device history (Clerk auth)

Returns a single deployment with all per-device run history. Requires Clerk Bearer token.

curl
curl -H "Authorization: Bearer <clerk_jwt>" https://fixpoint-3.polsia.app/api/intune/deployments/5
Response 200
{
  "id": 5,
  "displayName": "Fix W3SVC drift",
  "status": "active",
  "runSummary": { "pass": 42, "fail": 2, "unknown": 0 },
  "deviceRuns": [
    {
      "deviceId": "device-001",
      "deviceName": "WIN-CLI-42",
      "runStatus": "success",
      "resultCode": 0,
      "runAt": "2026-06-10T18:00:00Z"
    }
  ]
}
POST /api/intune/deployments/:id/trigger Trigger on-demand remediation on device (Clerk auth)

Triggers the deployment's remediation script on a specific device immediately. Requires Clerk Bearer token.

FieldTypeDescription
deviceIdstringrequiredIntune managedDevice ID
curl
curl -X POST https://fixpoint-3.polsia.app/api/intune/deployments/5/trigger \n
  -H "Authorization: Bearer <clerk_jwt>" \n
  -H "Content-Type: application/json" \n
  -d '{"deviceId":"device-001"}'
Response 200
{ "success": true, "deviceId": "device-001" }

Devices & Remediation History

GET /api/intune/devices List managed Intune devices (Clerk auth)

Returns all managed devices from the org's Intune tenant with compliance state. Requires Clerk Bearer token.

curl
curl -H "Authorization: Bearer <clerk_jwt>" https://fixpoint-3.polsia.app/api/intune/devices
Response 200
{
  "tenantId": "abc123...",
  "deviceCount": 47,
  "devices": [
    {
      "id": "device-001",
      "deviceName": "WIN-CLI-42",
      "userDisplayName": "Jane Smith",
      "osVersion": "Windows 11 23H2",
      "managementState": "Managed",
      "complianceState": "Compliant",
      "lastSyncDateTime": "2026-06-10T17:30:00Z"
    }
  ]
}
GET /api/intune/remediations/:deviceId Get remediation run history for a device (Clerk auth)

Returns all Fixpoint remediation run history for a specific Intune device. Requires Clerk Bearer token.

curl
curl -H "Authorization: Bearer <clerk_jwt>" https://fixpoint-3.polsia.app/api/intune/remediations/device-001
Response 200
{
  "deviceId": "device-001",
  "remediations": [
    {
      "deploymentId": 5,
      "runStatus": "success",
      "resultCode": 0,
      "runAt": "2026-06-10T18:00:00Z"
    }
  ]
}

API Key Management

GET /api-key Get key info (Clerk auth)

Returns key metadata (prefix, last_used, created_at) but never the raw key. Requires Clerk Bearer token.

curl
curl -H "Authorization: Bearer <clerk_jwt>" https://fixpoint-3.polsia.app/api/api-key
Response 200
{
  "has_key": true,
  "key_name": "Production",
  "key_prefix": "fp_live_a1b2...",
  "last_used": "2026-06-09T12:00:00Z",
  "created_at": "2026-06-01T09:00:00Z"
}
POST /api-key Create or rotate key (Clerk auth)

Creates a new API key or rotates the existing one. The raw key is returned only once — store it immediately. Requires Clerk Bearer token.

FieldTypeDescription
namestringOptional key label — e.g. "Production", "CI"
curl
curl -X POST https://fixpoint-3.polsia.app/api/api-key \n
  -H "Authorization: Bearer <clerk_jwt>" \n
  -H "Content-Type: application/json" \n
  -d '{"name":"Production"}'
Response 201
{
  "api_key": "fp_live_c3d4e5...",   ← raw key, shown once only
  "key_prefix": "fp_live_c3d4",
  "name": "Production",
  "message": "Save this key — it will not be shown again."
}
DELETE /api-key Revoke current key (Clerk auth)

Revokes the current API key. Any integration using the old key will immediately fail with 401. Requires Clerk Bearer token.

curl
curl -X DELETE https://fixpoint-3.polsia.app/api/api-key \n
  -H "Authorization: Bearer <clerk_jwt>"
Response 200
{ "message": "API key revoked" }

Webhooks

Configure outbound webhook endpoints to receive real-time event notifications. All webhooks are signed with HMAC-SHA256 so you can verify payload authenticity. Register webhooks via POST /api/webhooks.

EVENT drift.detected

Fired when a service state diverges from the known-good baseline. Payload includes service details and detected state.

Webhook payload — drift.detected
{
  "service_id": 12,
  "service_name": "W3SVC",
  "details": {
    "vm_host": "WIN-SRV-01",
    "detected_state": "Stopped",
    "drift_type": "service_stopped"
  }
}
EVENT script.generated

Fired when the AI generates a PowerShell remediation script for a drifted service.

Webhook payload — script.generated
{
  "service_id": 12,
  "service_name": "W3SVC",
  "details": {
    "script_hash": "a1b2c3d4e5f6..."
  }
}
EVENT sandbox.passed

Fired when a generated script passes sandbox verification and is queued for deployment.

Webhook payload — sandbox.passed
{
  "service_id": 12,
  "service_name": "W3SVC",
  "sandbox_attempt_id": 7,
  "result": "approved"
}
EVENT sandbox.failed

Fired when a generated script is blocked by the sandbox (destructive cmdlets detected, non-zero exit, or execution error).

Webhook payload — sandbox.failed
{
  "service_id": 12,
  "service_name": "W3SVC",
  "sandbox_attempt_id": 8,
  "result": "blocked",
  "reason": "Destructive cmdlet Remove-Item detected"
}
EVENT script.deployed

Fired when a script is successfully deployed and executed on the target endpoint.

Webhook payload — script.deployed
{
  "service_id": 12,
  "service_name": "W3SVC",
  "deployed_at": "2026-06-07T16:55:00Z",
  "exit_code": 0
}
EVENT script.failed

Fired when a deployed script returns a non-zero exit code.

Webhook payload — script.failed
{
  "service_id": 12,
  "service_name": "W3SVC",
  "exit_code": 1,
  "error": "Access denied"
}

Verifying webhook signatures

Every webhook request includes an X-Fixpoint-Signature header — a HMAC-SHA256 hex digest of the raw request body, signed with your webhook's secret.

Node.js verification
const crypto = require('crypto');
const secret = 'your_webhook_secret'; // from POST /api/webhooks response

function verifyWebhook(rawBody, signature) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  // Use timingSafeEqual to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expected, 'hex')
  );
}

// In your webhook handler:
const sig = req.headers['x-fixpoint-signature'];
if (!verifyWebhook(rawBodyBuffer, sig)) {
  return res.status(401).send('Invalid signature');
}
Python verification
import hmac, hashlib

def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        raw_body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
POST /api/webhooks Register a webhook endpoint
FieldTypeDescription
urlstringrequiredHTTPS endpoint to POST events to
eventsstring[]requiredArray of event types to subscribe to
curl
curl -X POST https://fixpoint-3.polsia.app/api/webhooks \n
  -H "Content-Type: application/json" \n
  -H "X-API-Key: fp_live_..." \n
  -d '{"url":"https://your-app.example.com/webhooks/fixpoint","events":["drift.detected","script.deployed"]}'
Response 201
{
  "webhook": {
    "id": 3,
    "url": "https://your-app.example.com/webhooks/fixpoint",
    "events": ["drift.detected", "script.deployed"],
    "secret": "whsec_a1b2c3...",  ← shown once — store securely
    "active": true,
    "created_at": "2026-06-10T00:00:00Z"
  }
}
GET /api/webhooks List registered webhooks
curl
curl -H "X-API-Key: fp_live_..." https://fixpoint-3.polsia.app/api/webhooks

Error Codes

400 { "error": "vm_host and service_name are required" } — Missing required fields on POST /services
401 { "error": "Missing X-API-Key header" } — No API key header sent
401 { "error": "Invalid API key" } — Key not found, revoked, or belongs to another org
403 { "error": "Insufficient permissions" } — Clerk auth — user lacks owner/admin role for this action
404 { "error": "Service not found" } — Service ID does not exist or is not owned by your org
502 { "error": "Drift check failed: ..." } — Could not reach VM or execute PowerShell query (WinRM not accessible)
502 { "error": "Script generation failed: ..." } — OpenAI model error or quota exceeded
503 { "error": "Webhook delivery failed: ..." } — Registered endpoint returned non-2xx for all retries

Usage Notes

  • All endpoints are scoped to your organization — no cross-account data access is possible.
  • Drift check executes Get-Service via PowerShell against the target VM. Ensure WinRM is open on port 5985 (HTTP) or 5986 (HTTPS) on the endpoint.
  • Generated remediation scripts include Start-Service or Restart-Service — blocked if they contain destructive cmdlets (Remove-Item, Stop-Process, Clear-EventLog, etc.).
  • Script generation uses OpenAI — on drift, expect 1–3s latency before the remediation script is returned.
  • Poll interval is not enforced via the API — use POST /services/:id/trigger-scan from your RMM scheduler instead.
  • Webhook delivery retries 3× with exponential backoff (1s, 10s, 60s) on failure. Failed deliveries are logged in the webhook_deliveries table.
  • Sandbox runs scripts in an isolated container — script execution time is capped at 30 seconds.