Parascope Docs

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/v1

Authentication

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

TierPrefixPermissionsUse Case
Serviceps_svc_Read/write for assigned resourcesService integrations, automated pipelines
Adminps_adm_Full access to all resourcesCLI tools, admin scripts
Readonlyps_ro_Read-only accessDashboards, monitoring
Userps_usr_Inherits user's permissions and data scopesPersonal API access, scripts

Public Endpoints (no auth required)

  • /health - Health check
  • /docs, /redoc, /openapi.json - API documentation
  • /metrics - Prometheus metrics

Authentication Flow

  1. Client sends X-API-Key: ps_svc_xxx... header
  2. API validates key hash against database
  3. Permissions checked against resource/action
  4. Request processed or 401/403 returned

Rate Limiting

  • Authenticated requests: 100 req/min per key by default (some endpoints, such as ParaQL and bulk change queries, have their own per-path limits)
  • Token bucket algorithm with burst capacity
  • Exceeding a limit returns 429 Too Many Requests
  • 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 /health

Returns 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-items

Retrieves a paginated list of configuration items with optional filtering.

Query Parameters:

ParameterTypeDefaultDescription
statusstringactiveFilter by lifecycle status: active, inactive, archived, or all
offsetinteger0Pagination offset
limitinteger50Number of items per page
sort_bystringcreated_atField to sort by
sort_orderstringdescSort order: asc or desc
filterstring-Advanced filter: field:operator:value (can be repeated)

Status Parameter Details:

  • active (default): Returns only CIs currently discoverable and monitored
  • inactive: Returns CIs not seen for the configured threshold period
  • archived: Returns soft-deleted CIs awaiting cleanup
  • all: Returns all CIs regardless of status

Filter Operators:

OperatorDescriptionExample
eqEqualsfilter=namespace:eq:default
neNot equalsfilter=status:ne:archived
gt, gteGreater than (or equal)filter=created_at:gt:2024-01-01
lt, lteLess than (or equal)filter=last_seen:lt:2024-06-01
likeContains (case-sensitive)filter=name:like:nginx
ilikeContains (case-insensitive)filter=name:ilike:NGINX
startswithStarts withfilter=namespace:startswith:prod-
inIn list (comma-separated)filter=ci_type:in:kubernetes.pod,kubernetes.service
ninNot in listfilter=namespace:nin:kube-system,default
nullIs nullfilter=namespace:null
notnullIs not nullfilter=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:

ParameterTypeDescription
include_type_databoolLoad type-specific data via SQL JOIN (requires ci_type filter)
include_attributeslistSpecific 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_type filter 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": {}
  }
}

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 archived but remains in the database
  • The CI's status is set to archived and status_updated_at is updated
  • Archived CIs are excluded from default queries unless status=all or status=archived is 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}/relationships

Retrieves one page of a configuration item's relationships (incoming and outgoing) as a paginated envelope with items, total, offset, limit, has_more, and next_cursor fields.

Path Parameters:

  • uuid: The UUID of the configuration item

Query Parameters:

  • limit: Maximum results per page (default: 100, maximum 5000)
  • offset: Pagination offset (default: 0)
  • cursor: Opaque keyset cursor from a prior page's next_cursor
  • include_inactive: Include archived/inactive relationships (default: false)
  • relationship_types: Comma-separated filter by relationship type (e.g. runs_on,manages)
  • direction: outgoing or incoming (omit for both); a cursor is only valid for the filter set that made it
  • sort_by: order the whole result set across both directions by relationship_type, related_ci_name, or related_ci_type; any other value returns 422
  • sort_order: asc (default) or desc; requires sort_by (sending it on its own returns 422)

Envelope semantics: total counts raw relationship rows, including rows whose neighbor CI no longer exists. Those rows are omitted from items, so a fully drained walk can return fewer items than total, and a page can come back empty with has_more still true. Detect the end of a walk with has_more and next_cursor, never with an empty items list or offset arithmetic. During a cursor walk the echoed offset stays at the value you requested. Sorted pages are cursor-only: sort_by together with an offset above 0 returns 422, so walk a sorted result set with next_cursor. A sorted page's next_cursor is bound to the sort that produced it and returns 422 if replayed with a different (or missing) sort_by or sort_order, just as an unsorted cursor returns 422 if replayed with sort_by.

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: 100, max 5000)
  • cursor: Opaque keyset cursor from a prior page's next_cursor

Returns a paginated {items, total, offset, limit, has_more, next_cursor} envelope, newest first. Envelope semantics: total counts change records. A record whose field-change list resolves to empty is counted in total but omitted from items, so a page can return fewer items than limit while more history remains. Detect the end of a walk with has_more and next_cursor, never with the length of items.

Get Global Change History

GET /api/v1/changes

Retrieves change history across all configuration items with advanced filtering and pagination.

Query Parameters:

ParameterTypeDefaultDescription
limitinteger100Maximum number of results (max: 1000)
offsetinteger0Pagination offset
start_datedatetime-Start of time window (ISO 8601)
end_datedatetime-End of time window (ISO 8601)
sort_bystringchanged_atField to sort by
sort_orderstringdescSort order: asc or desc
searchstring-Text search across CI names and changed fields
filterstring[]-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 name
  • changed_at: Filter by change timestamp
  • ci_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 fields
  • text/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.csv

JSON 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/stats

Retrieves aggregated change statistics for dashboard visualization.

Query Parameters:

ParameterTypeDefaultDescription
start_datedatetime90 days agoStart of time window (ISO 8601)
end_datedatetime-End of time window (ISO 8601)
group_bystringhourGrouping 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. That pre-aggregation covers the last 90 days, so a request without start_date returns the last 90 days rather than all time. The window actually covered is always in the response's time_range, so read the totals against that rather than assuming.

Earlier windows are still available: pass an explicit start_date and the statistics are computed from the change history itself, which is retained far longer (see Change History). Those requests read more data, so they are slower and may time out on a very wide window; narrow the range with end_date if it does.

Search Changes

GET /api/v1/changes/search

Performs full-text search across change history.

Query Parameters:

ParameterTypeRequiredDescription
querystringYesSearch query (minimum 2 characters)
limitintegerNoMaximum results (default: 50, max: 500)
offsetintegerNoPagination offset
start_datedatetimeNoFilter by start date
end_datedatetimeNoFilter by end date
filterstring[]NoAdvanced filters in format field:operator:value

Response includes search time in milliseconds for performance monitoring.

Refresh Change Statistics

POST /api/v1/changes/refresh-stats

Internal: 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/collectors

Retrieves a list of registered collectors with optional filtering.

Query Parameters:

ParameterTypeDescription
namestringFilter by collector name (exact match)
collector_type or typestringFilter by collector type (e.g., kubernetes, ceph)
statusstringFilter 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=ceph

Note: Multiple collectors can have the same name as long as they have different types.

Get Collector Details

GET /api/v1/collectors/{id}

Collector Create / Update / Delete (Deprecated)

Deprecated: these endpoints now return 410 Gone. Collectors are provisioned automatically when you add a data source. Manage data sources through the Sources endpoints instead.

POST   /api/v1/collectors           → 410 Gone
PUT    /api/v1/collectors/{id}      → 410 Gone
PATCH  /api/v1/collectors/{id}      → 410 Gone
DELETE /api/v1/collectors/{id}      → 410 Gone

Each returns:

{
  "detail": "This endpoint has been deprecated. Use /api/v1/sources for source management."
}

To create, update, or remove a data source (which provisions or tears down the underlying collector), use POST /api/v1/collectors/{collector_id}/sources, PUT /api/v1/sources/{id}, and DELETE /api/v1/sources/{id}. All three are documented under Sources below.

Trigger Manual Collection

POST /api/v1/collectors/{id}/trigger

Check Collector Health

GET /api/v1/collectors/{id}/health

Returns 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/sources

Retrieves all data sources across all collectors.

Query Parameters:

ParameterTypeDescription
collector_idintegerFilter by collector ID
enabledbooleanFilter by enabled status
statusstringFilter by source status
limitintegerNumber of items per page (default: 50)
offsetintegerPagination 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}/sources

Retrieves 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}/sources

Adds a new data source to a collector. Source credentials are not part of this request body -- set them with a separate PUT /api/v1/sources/{id}/credentials call, which stores them securely server-side (AES-256-GCM-encrypted, per-tenant). Credentials are never returned in responses.

Request Body (Kubernetes Example):

{
  "name": "staging-cluster",
  "endpoint": "https://k8s-staging.example.com:6443",
  "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",
  "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",
  "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",
  "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. This endpoint does not touch credentials -- set or replace them with PUT /api/v1/sources/{id}/credentials.

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
  • Credentials are set through PUT /api/v1/sources/{id}/credentials, not this endpoint, and are stored AES-256-GCM-encrypted per tenant
  • Credential values are never returned in responses; a single source's credentials can be read back only via the audited, permissioned GET /api/v1/sources/{id}/credentials/reveal

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"
}

Report Source Health

PUT /api/v1/sources/{id}/health

Internal: 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/all

Performs 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:

  1. Active: The CI is currently discoverable and being monitored

    • Default state for all new CIs
    • last_seen timestamp regularly updated by collectors
    • Included in default API queries
  2. Inactive: The CI has not been seen for the configured threshold

    • Automatically transitioned after the inactive threshold (default: 24 hours)
    • Can return to active if rediscovered by a collector
    • Not included in default queries unless explicitly requested
  3. 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

Every error is wrapped in a consistent envelope. There is no bare detail field:

{
  "error": {
    "id": "0198c0de-6f2a-7000-8000-3f5a2b1c9d4e",
    "code": "HTTP_404",
    "message": "ConfigurationItem not found: 6a1f…",
    "details": {},
    "path": "/api/v1/configuration-items/6a1f…",
    "method": "GET"
  }
}

id is unique per occurrence (quote it when reporting a problem). Common status codes:

  • 200: Success
  • 201: Created
  • 400: Bad Request (invalid parameters)
  • 404: Not Found (code: "HTTP_404")
  • 422: Unprocessable Entity. Two flavors. Request validation failures, which FastAPI raises from the parameter declarations themselves (an over-limit limit, a non-integer offset), carry code: "VALIDATION_ERROR" with the field errors under details.errors. Rejections the route raises itself (a malformed or contradictory pagination cursor, an invalid direction) carry code: "HTTP_422" with the reason in message.
  • 500: Internal Server Error (code: "INTERNAL_SERVER_ERROR")

Best Practices

  1. Status Filtering: Always consider which CI states you need when querying

    • Use default (active) for operational dashboards
    • Use all for audit trails and historical analysis
    • Use inactive to identify potentially orphaned resources
  2. Soft Deletes: Leverage soft deletes for safer CI management

    • Archived CIs can be recovered by restarting the collector within the retention period
    • Monitor the archived status to track removal patterns
  3. Performance: Use filtering and pagination for large datasets

    • Combine multiple filters to narrow results
    • Use appropriate limit values for your use case
  4. Monitoring: Track lifecycle metrics to understand your infrastructure patterns

    • High inactive counts may indicate configuration drift
    • Frequent state transitions may indicate unstable resources