Parascope API Reference
REST API endpoints, authentication, and query parameters
Overview
The Parascope API provides a RESTful interface for managing Configuration Items (CIs) and their lifecycle states. The API supports advanced querying, filtering, and lifecycle management for discovered infrastructure components.
Base URL
https://your-company.parascope.io/api/v1Authentication
The Parascope API uses API key authentication for all non-public endpoints. Keys are passed via the X-API-Key header (never query parameters for security).
Key Tiers
| Tier | Prefix | Permissions | Use Case |
|---|---|---|---|
| Service | ps_svc_ | Read/write for assigned resources | Service integrations, automated pipelines |
| Admin | ps_adm_ | Full access to all resources | CLI tools, admin scripts |
| Readonly | ps_ro_ | Read-only access | Dashboards, monitoring |
| User | ps_usr_ | Inherits user's permissions and data scopes | Personal API access, scripts |
Public Endpoints (no auth required)
/health- Health check/docs,/redoc,/openapi.json- API documentation/metrics- Prometheus metrics
Authentication Flow
- Client sends
X-API-Key: ps_svc_xxx...header - API validates key hash against database
- Permissions checked against resource/action
- Request processed or 401/403 returned
Rate Limiting
- Authenticated requests: 100 req/min per key (configurable)
- Unauthenticated requests: 50 req/min per IP
- Token bucket algorithm with burst capacity
- Response headers:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset
Security Audit Log
All authentication events are logged to the security audit log:
- Successful/failed auth attempts
- Key creation/revocation
- Permission denied events
API Endpoints
Health Check
Check API Health
GET /healthReturns the health status of the API service.
Response:
{
"status": "healthy",
"timestamp": "2025-07-08T12:00:00Z"
}Configuration Items
List Configuration Items
GET /api/v1/configuration-itemsRetrieves a paginated list of configuration items with optional filtering.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
status | string | active | Filter by lifecycle status: active, inactive, archived, or all |
offset | integer | 0 | Pagination offset |
limit | integer | 50 | Number of items per page |
sort_by | string | created_at | Field to sort by |
sort_order | string | desc | Sort order: asc or desc |
filter | string | - | Advanced filter: field:operator:value (can be repeated) |
Status Parameter Details:
active(default): Returns only CIs currently discoverable and monitoredinactive: Returns CIs not seen for the configured threshold periodarchived: Returns soft-deleted CIs awaiting cleanupall: Returns all CIs regardless of status
Filter Operators:
| Operator | Description | Example |
|---|---|---|
eq | Equals | filter=namespace:eq:default |
ne | Not equals | filter=status:ne:archived |
gt, gte | Greater than (or equal) | filter=created_at:gt:2024-01-01 |
lt, lte | Less than (or equal) | filter=last_seen:lt:2024-06-01 |
like | Contains (case-sensitive) | filter=name:like:nginx |
ilike | Contains (case-insensitive) | filter=name:ilike:NGINX |
startswith | Starts with | filter=namespace:startswith:prod- |
in | In list (comma-separated) | filter=ci_type:in:kubernetes.pod,kubernetes.service |
nin | Not in list | filter=namespace:nin:kube-system,default |
null | Is null | filter=namespace:null |
notnull | Is not null | filter=raw_data:notnull |
Example Requests:
# Get active CIs (default)
curl "https://your-company.parascope.io/api/v1/configuration-items"
# Get all CIs including inactive and archived
curl "https://your-company.parascope.io/api/v1/configuration-items?status=all"
# Get only inactive CIs
curl "https://your-company.parascope.io/api/v1/configuration-items?status=inactive"
# Get active pods in default namespace
curl "https://your-company.parascope.io/api/v1/configuration-items?status=active&filter=ci_type:eq:kubernetes.pod&filter=namespace:eq:default"
# Get CIs with name containing 'nginx', including inactive
curl "https://your-company.parascope.io/api/v1/configuration-items?status=all&filter=name:like:nginx"Response:
{
"items": [
{
"ci_id": "3936b501-788f-4c0d-b3a7-a999f77fac8c",
"name": "nginx-deployment-abc123",
"namespace": "default",
"ci_type": "kubernetes.pod",
"status": "active",
"status_updated_at": null,
"last_seen": "2025-07-08T12:00:00Z",
"created_at": "2025-07-01T10:00:00Z",
"updated_at": "2025-07-08T12:00:00Z",
"raw_data": {}
}
],
"total": 150,
"offset": 0,
"limit": 50
}Type-Specific Data Loading:
| Parameter | Type | Description |
|---|---|---|
include_type_data | bool | Load type-specific data via SQL JOIN (requires ci_type filter) |
include_attributes | list | Specific JSONB paths to extract from raw_data |
The include_type_data=true parameter efficiently loads type-specific data (e.g., for postgresql.table or kubernetes.pod) in a single query, avoiding N+1 query problems. The type-specific data is embedded in the attributes field of each response item.
Example: Efficient Table Listing
# Get all PostgreSQL tables in a database with metrics - single query
curl -H "X-API-Key: $PARASCOPE_API_KEY" \
"https://your-company.parascope.io/api/v1/configuration-items?\
filter=ci_type:eq:postgresql.table&\
filter=namespace:startswith:mydb.&\
include_type_data=true&\
limit=1000"
# Response structure:
{
"items": [
{
"id": "uuid",
"type": "postgresql.table",
"attributes": {
"name": "users",
"namespace": "mydb.public",
"postgresql_table": {
"schema_name": "public",
"kind": "r",
"metrics": {
"total_size_bytes": 8192,
"estimated_row_count": 100,
"idx_scan": 50,
"seq_scan": 10
}
}
}
}
],
"total": 91,
"has_more": false
}When to use include_type_data:
- Building detail views that need type-specific fields (metrics, configuration)
- Displaying tables/lists with columns from type-specific data
- Avoiding multiple API calls when you need data for many CIs
When NOT to use include_type_data:
- Simple listing without type-specific fields (use default response)
- Fetching a single CI (use
/configuration-items/{uuid}instead) - When
ci_typefilter is not specified (parameter is ignored)
Get Configuration Item Details
GET /api/v1/configuration-items/{uuid}Retrieves detailed information about a specific configuration item.
Path Parameters:
uuid: The UUID of the configuration item
Response:
{
"ci_id": "3936b501-788f-4c0d-b3a7-a999f77fac8c",
"name": "nginx-deployment-abc123",
"namespace": "default",
"ci_type": "kubernetes.pod",
"status": "active",
"status_updated_at": null,
"last_seen": "2025-07-08T12:00:00Z",
"created_at": "2025-07-01T10:00:00Z",
"updated_at": "2025-07-08T12:00:00Z",
"raw_data": {
"metadata": {},
"spec": {},
"status": {}
}
}Create Configuration Item
POST /api/v1/configuration-itemsCreates a new configuration item (typically done by collectors).
Request Body:
{
"name": "new-service",
"namespace": "production",
"ci_type": "kubernetes.service",
"raw_data": {}
}Update Configuration Item
PUT /api/v1/configuration-items/{uuid}Updates an existing configuration item.
Path Parameters:
uuid: The UUID of the configuration item
Request Body:
{
"name": "updated-service",
"namespace": "production",
"ci_type": "kubernetes.service",
"raw_data": {}
}Delete Configuration Item (Soft Delete)
DELETE /api/v1/configuration-items/{uuid}Performs a soft delete on a configuration item by setting its status to archived.
Path Parameters:
uuid: The UUID of the configuration item
Important Notes:
- This endpoint performs a soft delete - the CI is marked as
archivedbut remains in the database - The CI's
statusis set toarchivedandstatus_updated_atis updated - Archived CIs are excluded from default queries unless
status=allorstatus=archivedis specified - Archived CIs will be permanently removed after the configured retention period by the cleanup job
Response:
{
"message": "Configuration item marked as archived",
"ci_id": "3936b501-788f-4c0d-b3a7-a999f77fac8c",
"status": "archived",
"status_updated_at": "2025-07-08T12:30:00Z"
}Get Configuration Item Relationships
GET /api/v1/configuration-items/{uuid}/relationshipsRetrieves all relationships for a specific configuration item.
Path Parameters:
uuid: The UUID of the configuration item
Change History
Get Configuration Item Change History
GET /api/v1/ci-changes/{uuid}Retrieves the change history for a specific configuration item.
Path Parameters:
uuid: The UUID of the configuration item
Query Parameters:
offset: Pagination offset (default: 0)limit: Number of items per page (default: 50)
Get Global Change History
GET /api/v1/changesRetrieves change history across all configuration items with advanced filtering and pagination.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 100 | Maximum number of results (max: 1000) |
offset | integer | 0 | Pagination offset |
start_date | datetime | - | Start of time window (ISO 8601) |
end_date | datetime | - | End of time window (ISO 8601) |
sort_by | string | changed_at | Field to sort by |
sort_order | string | desc | Sort order: asc or desc |
search | string | - | Text search across CI names and changed fields |
filter | string[] | - | Advanced filters in format field:operator:value |
Supported Filter Fields:
change_type: Filter by change type (CREATED, UPDATED, DELETED)ci_type: Filter by CI type identifier (e.g.,kubernetes.pod)ci_name: Filter by CI namechanged_at: Filter by change timestampci_id: Filter by CI UUID
Content Negotiation:
Set the Accept header to control response format:
application/json(default): Returns paginated JSON response with actual objects/arrays for complex fieldstext/csv: Returns streaming CSV download for efficient large exports
Example Request:
# Get created pods in the last 24 hours
curl "https://your-company.parascope.io/api/v1/changes?filter=change_type:eq:CREATED&filter=ci_type:eq:kubernetes.pod&start_date=2025-01-07T00:00:00"
# Export all deleted items as CSV
curl -H "Accept: text/csv" "https://your-company.parascope.io/api/v1/changes?filter=change_type:eq:DELETED" > deleted_items.csvJSON Response Example:
{
"items": [
{
"id": "12345",
"ci_id": "3936b501-788f-4c0d-b3a7-a999f77fac8c",
"ci_name": "nginx-deployment",
"ci_namespace": "default",
"ci_type": "kubernetes.deployment",
"changed_at": "2025-01-08T10:30:00Z",
"change_type": "UPDATED",
"changes": [
{
"field": "replicas",
"old_value": 3,
"new_value": 5
},
{
"field": "conditions",
"old_value": [
{"type": "Ready", "status": "True", "last_transition_time": "2025-01-08T09:00:00Z"},
{"type": "PodScheduled", "status": "True", "last_transition_time": "2025-01-08T08:59:00Z"}
],
"new_value": [
{"type": "Ready", "status": "True", "last_transition_time": "2025-01-08T10:30:00Z"},
{"type": "PodScheduled", "status": "True", "last_transition_time": "2025-01-08T08:59:00Z"}
]
}
]
}
],
"total": 250,
"limit": 100,
"offset": 0
}Note: Complex fields like Kubernetes conditions are returned as actual objects/arrays, not JSON strings.
Get Change Statistics
GET /api/v1/changes/statsRetrieves aggregated change statistics for dashboard visualization.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
start_date | datetime | - | Start of time window (ISO 8601) |
end_date | datetime | - | End of time window (ISO 8601) |
group_by | string | hour | Grouping interval: hour, day, or week |
Response Example:
{
"total_changes": 1250,
"affected_cis": 89,
"changes_by_type": {
"created": 150,
"updated": 1050,
"archived": 50
},
"top_changed_ci_types": [
{
"ci_type": "kubernetes.pod",
"count": 800
},
{
"ci_type": "kubernetes.service",
"count": 200
}
],
"time_range": {
"start": "2025-01-01T00:00:00Z",
"end": "2025-01-08T00:00:00Z"
}
}Note: Statistics are served from a materialized view for optimal performance.
Search Changes
GET /api/v1/changes/searchPerforms full-text search across change history.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query (minimum 2 characters) |
limit | integer | No | Maximum results (default: 50, max: 500) |
offset | integer | No | Pagination offset |
start_date | datetime | No | Filter by start date |
end_date | datetime | No | Filter by end date |
filter | string[] | No | Advanced filters in format field:operator:value |
Response includes search time in milliseconds for performance monitoring.
Refresh Change Statistics
POST /api/v1/changes/refresh-statsInternal — Statistics are refreshed automatically on a schedule.
Manually triggers a refresh of the change statistics materialized view. This is normally handled automatically by a scheduled job.
Collectors
List Collectors
GET /api/v1/collectorsRetrieves a list of registered collectors with optional filtering.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
name | string | Filter by collector name (exact match) |
collector_type or type | string | Filter by collector type (e.g., kubernetes, ceph) |
status | string | Filter by collector status |
Example Requests:
# Get all collectors
GET /api/v1/collectors
# Get all Ceph collectors
GET /api/v1/collectors?collector_type=ceph
# Get collector by name and type
GET /api/v1/collectors?name=ceph-collector-production&type=cephNote: Multiple collectors can have the same name as long as they have different types.
Create Collector
POST /api/v1/collectorsInternal — Collectors are provisioned automatically during source setup.
Register a new collector. The combination of name and type must be unique.
Request Body:
{
"name": "ceph-collector-production",
"type": "ceph",
"endpoint": "https://your-company.parascope.io/collectors/ceph",
"config": {
"clusters": ["production"],
"collection_mode": "periodic"
},
"schedule_config": {
"enabled": true,
"interval_minutes": 5
}
}Get Collector Details
GET /api/v1/collectors/{id}Update Collector
PUT /api/v1/collectors/{id}Delete Collector
DELETE /api/v1/collectors/{id}Trigger Manual Collection
POST /api/v1/collectors/{id}/triggerCheck Collector Health
GET /api/v1/collectors/{id}/healthReturns the health status of a specific collector service. Supports the universal health check format.
Response:
{
"status": "healthy",
"message": "All sources operational",
"timestamp": "2025-08-01T10:00:00Z",
"capabilities": {
"supports_universal_format": true,
"supports_multi_source": true
},
"subsystems": {
"source_1": {
"status": "healthy",
"last_collection": "2025-08-01T09:55:00Z"
},
"source_2": {
"status": "degraded",
"last_error": "Connection timeout"
}
}
}Sources (Multi-Source Management)
List All Sources
GET /api/v1/sourcesRetrieves all data sources across all collectors.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
collector_id | integer | Filter by collector ID |
enabled | boolean | Filter by enabled status |
status | string | Filter by source status |
limit | integer | Number of items per page (default: 50) |
offset | integer | Pagination offset (default: 0) |
Example Response:
{
"items": [
{
"id": 1,
"collector_id": 1,
"name": "production-cluster",
"endpoint": "https://k8s-prod.example.com:6443",
"status": "enabled",
"health_status": {
"status": "healthy",
"last_check": "2025-08-01T10:00:00Z"
},
"last_collection": "2025-08-01T09:55:00Z",
"schedule_config": {
"enabled": true,
"interval_minutes": 5
},
"created_at": "2025-07-01T00:00:00Z",
"updated_at": "2025-08-01T09:55:00Z"
}
],
"total": 10,
"offset": 0,
"limit": 50
}Get Sources for a Collector
GET /api/v1/collectors/{collector_id}/sourcesRetrieves all sources managed by a specific collector.
Example Response:
[
{
"id": 1,
"name": "production-cluster",
"endpoint": "https://k8s-prod.example.com:6443",
"status": "enabled",
"config": {
"verify_ssl": true,
"collection_mode": "hybrid"
},
"schedule_config": {
"enabled": true,
"interval_minutes": 5
},
"health_status": {
"status": "healthy",
"components": {
"api_server": "reachable",
"metrics_server": "reachable"
}
},
"last_collection": "2025-08-01T09:55:00Z"
}
]Add Source to Collector
POST /api/v1/collectors/{collector_id}/sourcesAdds a new data source to a collector. Credentials are stored securely in the credential store.
Request Body (Kubernetes Example):
{
"name": "staging-cluster",
"endpoint": "https://k8s-staging.example.com:6443",
"token": "eyJhbGciOiJSUzI1NiIsImtpZCI...",
"config": {
"verify_ssl": false,
"collection_mode": "periodic",
"enabled_collectors": ["pods", "nodes", "deployments"]
},
"schedule_config": {
"enabled": true,
"interval_minutes": 10
}
}Request Body (Ceph Example):
{
"name": "production-ceph",
"endpoint": "https://ceph-prod.example.com:8443",
"username": "admin",
"password": "secure-password",
"config": {
"verify_ssl": true,
"timeout": 30,
"enabled_collectors": ["cluster", "osd", "pool", "mon", "mgr"]
},
"schedule_config": {
"enabled": true,
"interval_minutes": 5
}
}Request Body (Proxmox Example):
{
"name": "proxmox-cluster-1",
"endpoint": "https://pve.example.com:8006",
"username": "monitor@pve",
"password": "secure-password",
"config": {
"verify_ssl": false,
"enabled_collectors": ["cluster", "node", "vm", "container", "storage"]
},
"schedule_config": {
"enabled": true,
"interval_minutes": 5
}
}Response:
{
"id": 2,
"collector_id": 1,
"name": "staging-cluster",
"endpoint": "https://k8s-staging.example.com:6443",
"status": "enabled",
"config": {
"verify_ssl": false,
"collection_mode": "periodic"
},
"schedule_config": {
"enabled": true,
"interval_minutes": 10
},
"created_at": "2025-08-01T10:00:00Z"
}Get Source Details
GET /api/v1/sources/{id}Retrieves detailed information about a specific source.
Response:
{
"id": 1,
"collector_id": 1,
"collector": {
"id": 1,
"name": "Kubernetes Collector",
"collector_type": "kubernetes"
},
"name": "production-cluster",
"endpoint": "https://k8s-prod.example.com:6443",
"username": null,
"status": "enabled",
"config": {
"verify_ssl": true,
"collection_mode": "hybrid"
},
"schedule_config": {
"enabled": true,
"interval_minutes": 5
},
"health_status": {
"status": "healthy",
"last_check": "2025-08-01T10:00:00Z",
"details": {
"api_server": "reachable",
"version": "v1.28.0"
}
},
"last_collection": "2025-08-01T09:55:00Z",
"last_error": null,
"created_at": "2025-07-01T00:00:00Z",
"updated_at": "2025-08-01T09:55:00Z"
}Update Source
PUT /api/v1/sources/{id}Updates a source configuration. Credentials can be updated by providing new values.
Request Body:
{
"name": "production-cluster-renamed",
"config": {
"verify_ssl": true,
"collection_mode": "hybrid",
"timeout": 60
},
"schedule_config": {
"enabled": false
}
}Note:
- Omitted fields retain their current values
- To update credentials, provide new
username/passwordortokenfields - Credentials are never returned in responses for security
Delete Source
DELETE /api/v1/sources/{id}Removes a data source. This operation:
- Disables further collections from this source
- Removes stored credentials
- Does NOT delete historical data collected from this source
Response:
{
"message": "Source deleted successfully"
}Check Source Health
POST /api/v1/sources/{id}/healthTriggers an on-demand health check for a specific source. The API will make an HTTP request to the collector service's health endpoint to get the current status and update the source accordingly.
Response:
{
"source_id": 1,
"name": "production-cluster",
"status": "healthy",
"health_status": {
"status": "healthy",
"connections": {
"primary": "connected",
"messaging": "connected"
}
},
"last_check": "2025-08-01T10:00:00Z",
"message": "Health check completed: healthy"
}Report Source Health
PUT /api/v1/sources/{id}/healthInternal — This endpoint is called automatically by collectors. It is not intended for direct use.
Used by collectors to report health status for a specific source. This endpoint is called automatically by collectors during their operation to update the source's health status.
Request Body:
{
"status": "healthy",
"message": "Collection completed successfully",
"timestamp": 1738363200,
"duration": 2.5,
"consecutive_errors": 0
}Response:
{
"status": "ok",
"message": "Health status updated"
}Batch Operations
Check All Collector Health
GET /api/v1/collectors/health/allPerforms batch health checks for all registered collectors.
Response:
{
"timestamp": "2025-08-01T10:00:00Z",
"collectors": [
{
"id": 1,
"name": "Kubernetes Collector",
"status": "healthy",
"sources_total": 3,
"sources_healthy": 3
},
{
"id": 2,
"name": "Ceph Collector",
"status": "degraded",
"sources_total": 2,
"sources_healthy": 1,
"error": "1 source unhealthy"
}
]
}Lifecycle Management
Lifecycle States
Configuration Items in Parascope follow a three-state lifecycle:
-
Active: The CI is currently discoverable and being monitored
- Default state for all new CIs
last_seentimestamp regularly updated by collectors- Included in default API queries
-
Inactive: The CI has not been seen for the configured threshold
- Automatically transitioned after the inactive threshold (default: 24 hours)
- Can return to
activeif rediscovered by a collector - Not included in default queries unless explicitly requested
-
Archived: The CI has been soft-deleted or inactive beyond retention
- Set when explicitly deleted via API or after extended inactivity
- Scheduled for permanent removal after the archive retention period (default: 7 days)
- Not included in default queries unless explicitly requested
State Transitions
┌─────────┐ Not seen for ┌──────────┐ Retention ┌──────────┐
│ Active │ ─────────────────────> │ Inactive │ ──────────────────> │ Archived │
└─────────┘ inactive_threshold └──────────┘ period expires └──────────┘
^ │ │
│ │ │
└───────────────────────────────────┘ │
CI rediscovered │
│
Hard delete │
(cleanup) ▼Querying by Status
To include inactive or archived CIs in queries, use the status parameter:
# Get only active CIs (default behavior)
curl "https://your-company.parascope.io/api/v1/configuration-items"
# Get all CIs regardless of status
curl "https://your-company.parascope.io/api/v1/configuration-items?status=all"
# Get only inactive CIs
curl "https://your-company.parascope.io/api/v1/configuration-items?status=inactive"
# Get only archived CIs awaiting cleanup
curl "https://your-company.parascope.io/api/v1/configuration-items?status=archived"
# Combine with other filters
curl "https://your-company.parascope.io/api/v1/configuration-items?status=all&filter=namespace:eq:default"Configuration
Lifecycle thresholds are configurable by your administrator.
Error Responses
The API uses standard HTTP status codes and returns errors in a consistent format:
{
"detail": "Configuration item not found",
"status_code": 404,
"type": "NotFoundError"
}Common status codes:
200: Success201: Created400: Bad Request (invalid parameters)404: Not Found422: Unprocessable Entity (validation error)500: Internal Server Error
Best Practices
-
Status Filtering: Always consider which CI states you need when querying
- Use default (
active) for operational dashboards - Use
allfor audit trails and historical analysis - Use
inactiveto identify potentially orphaned resources
- Use default (
-
Soft Deletes: Leverage soft deletes for safer CI management
- Archived CIs can be recovered by restarting the collector within the retention period
- Monitor the
archivedstatus to track removal patterns
-
Performance: Use filtering and pagination for large datasets
- Combine multiple filters to narrow results
- Use appropriate
limitvalues for your use case
-
Monitoring: Track lifecycle metrics to understand your infrastructure patterns
- High inactive counts may indicate configuration drift
- Frequent state transitions may indicate unstable resources
Related Documentation
- Architecture - System design overview