Skip to main content
Standard structures and conventions used across all k0rdent APIs
This page describes the common patterns, data types, and conventions used throughout the k0rdent API to ensure consistency and predictability.

Response Envelope

All API responses use a consistent discriminated union envelope structure with a success boolean discriminator.

Type Definition

// Base response wrapper with discriminated union
type ApiResponse<T, M = {}> =
  | { success: true; data: T; meta: BaseMeta & M }  // Success with extendable meta
  | { success: false; error: ApiErrorBody; meta: BaseMeta }  // Error with fixed meta

Success Response

{
  "success": true,
  "data": {
    "id": "srv_abc123",
    "name": "compute-node-01",
    "state": "available"
  },
  "meta": {
    "requestId": "req_sfo1-1770564159296-7d4b9e1f3a5b",
    "timestamp": "2025-01-09T12:00:00.000Z"
  }
}

Error Response

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Server not found"
  },
  "meta": {
    "requestId": "req_sfo1-1770564159296-7d4b9e1f3a5b",
    "timestamp": "2025-01-09T12:00:00.000Z"
  }
}

Meta Object

The meta object is always present in responses and contains request tracking information.

Base Meta Fields

FieldTypeDescription
requestIdstringUnique request identifier for log correlation
timestampstringISO 8601 timestamp (UTC) for distributed debugging

Extended Meta Types

Success responses can extend meta with additional context: Pagination Meta:
{
  "success": true,
  "data": [...],
  "meta": {
    "requestId": "req_sfo1-1770564159296-7d4b9e1f3a5b",
    "timestamp": "2025-01-09T12:00:00.000Z",
    "pagination": {
      "total": 156,
      "page": 1,
      "pageSize": 25,
      "hasMore": true,
      "nextCursor": "srv_456"
    }
  }
}
Workflow Meta:
{
  "success": true,
  "data": {...},
  "meta": {
    "requestId": "req_sfo1-1770564159296-7d4b9e1f3a5b",
    "timestamp": "2025-01-09T12:00:00.000Z",
    "workflowId": "run_deploy_789",
    "estimatedDuration": 300000
  }
}

Resource Identifiers

Resources use globally unique, opaque IDs that do NOT contain region information. This decouples resource identity from physical location.

ID Format

Format: {prefix}_{base62}

Resource ID Prefixes

ResourcePrefixExample
Organizationorg_org_8TcVx2WkZddNmK3Pt9JwX7BzWrLM
Serversrv_srv_3KpQm9WnXccFjH2Ls8DkT6VzRqYU
Clustercls_cls_6NZtkvWLBbbmHfPi7L6oz7KZpqET
Stackstk_stk_5MfRp4WjYbbHmG8Nt2LvS9CxPqZK
Workflow Runrun_run_7NhTq6WlAbbKmF5Rt3MxU8DzSqWJ
Poolpool_pool_2LgPn8WmXccGjE7Mt4KwV9BySrTL
Allocationalloc_alloc_9QjSr3WnZddMmH6Pt5LxW2CzUrYK
API Keykey_key_4KfQm7WkYccJmG3Nt8MvX9BzSqWL
Eventevt_evt_6MgRp2WlXbbKmF9Rt5NxU3DzTqZJ
Resource IDs are 26 characters after the prefix, using base62 encoding (case-sensitive).

Request Identifiers

Every API request gets a unique Request ID for tracing, debugging, and correlation across services.

Format

Format: req_{region}-{timestamp}-{entropy}

Example

req_sfo1-1770564159296-7d4b9e1f3a5b
req_lax1-1770564205843-3c2f9a8e7b4d
req_ams1-1770564298172-9f3e8d2c1a5b

Components

  • req_ - Platform prefix for easy grepping in logs
  • sfo1 - Region code where request was processed
  • 1770564159296 - Unix timestamp in milliseconds
  • 7d4b9e1f3a5b - Random entropy (12 hex characters)
Request IDs are returned in the X-Request-Id response header and meta.requestId field.

Naming Conventions

URL Paths

RuleExample
Lowercase, hyphenated/ai-services
Plural nouns for collections/servers, /clusters
Singular for singletons/me, /health
Colon-prefixed route params/clusters/:clusterId

Field Names

RuleExample
camelCasecreatedAt, nodeCount
Suffix IDs with IdclusterId, organizationId
Past tense for timestampscreatedAt, updatedAt, deletedAt

Dates and Timestamps

All temporal fields use ISO 8601 format and are always treated as UTC.

Common Fields

FieldDescription
createdAtWhen the object was created
updatedAtWhen the object was last updated
deletedAtWhen the object was deleted (soft delete)

Example

{
  "id": "cls_abc123",
  "name": "production",
  "createdAt": "2025-01-09T12:00:00.000Z",
  "updatedAt": "2025-01-09T14:30:00.000Z"
}

Use of HTTP

HTTP Methods

The k0rdent API uses standard HTTP methods:
MethodPurpose
GETRetrieve resources (read-only)
POSTCreate new resources
PATCHUpdate existing resources (partial)
DELETEDelete resources

Content Type

All requests and responses use Content-Type: application/json unless otherwise specified.

Example Request

curl -X POST https://api.example.com/v1/region/sfo1/compute/clusters \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer key_4KfQm7WkYccJmG3Nt8MvX9BzSqWL" \
  -d '{
    "name": "production-cluster",
    "template": "k8s-standard"
  }'

Pagination

The k0rdent API supports both cursor-based and offset/limit pagination.

Cursor-Based Pagination

Recommended for real-time data:
GET /v1/region/global/infrastructure/servers?limit=50&cursor=srv_abc123
Response:
{
  "success": true,
  "data": [...],
  "meta": {
    "requestId": "req_sfo1-1770564159296-7d4b9e1f3a5b",
    "timestamp": "2025-01-09T12:00:00.000Z",
    "pagination": {
      "total": 156,
      "pageSize": 50,
      "hasMore": true,
      "nextCursor": "srv_xyz789"
    }
  }
}

Offset/Limit Pagination

For stable datasets:
GET /v1/region/global/infrastructure/servers?limit=50&offset=100
Response:
{
  "success": true,
  "data": [...],
  "meta": {
    "requestId": "req_sfo1-1770564159296-7d4b9e1f3a5b",
    "timestamp": "2025-01-09T12:00:00.000Z",
    "pagination": {
      "total": 156,
      "page": 3,
      "pageSize": 50,
      "hasMore": true
    }
  }
}

Pagination Parameters

ParameterDescriptionDefault
limitNumber of items per page (max 100)25
offsetSkip this many items0
cursorOpaque cursor for next page-

Filtering

You can filter resources by most attributes using query parameters:

Simple Filter

GET /v1/region/global/infrastructure/servers?state=available

Multiple Values

GET /v1/region/global/infrastructure/servers?state=available,provisioning

Example Response

All filtered results still use the standard response envelope with pagination.

Sorting

Sort resources in ascending or descending order:

Sort Ascending

GET /v1/region/global/infrastructure/servers?sort=name

Sort Descending

Use - prefix for descending:
GET /v1/region/global/infrastructure/servers?sort=-createdAt

Multiple Sort Fields

GET /v1/region/global/infrastructure/servers?sort=state,-createdAt

Field Design Rules

Use Objects Over Primitives

Always wrap values that might grow into objects:
// βœ… Extensible
interface Server {
  status: {
    state: 'available' | 'provisioning' | 'error'
    reason?: string
    since?: string
  }
  bmc: {
    address: string
    protocol?: 'ipmi' | 'redfish'
  }
}

// ❌ Will require breaking change
interface Server {
  status: 'available' | 'provisioning' | 'error'
  bmcAddress: string
}

Never Use Booleans for State

States often grow beyond two values:
// βœ… Extensible
interface Server {
  power: {
    state: 'on' | 'off' | 'unknown'
  }
}

// ❌ Trouble waiting to happen
interface Server {
  isOnline: boolean
}

Use IDs with Optional Expansion

Don’t embed full objects - use IDs and let clients request expansion:
// βœ… ID reference
{
  "id": "srv_123",
  "clusterId": "cls_456"
}

// βœ… Optional expansion with ?expand=cluster
{
  "id": "srv_123",
  "clusterId": "cls_456",
  "cluster": {
    "id": "cls_456",
    "name": "prod-cluster"
  }
}

Optional Fields

Unpopulated optional data is returned as follows:
  • Arrays and Objects may be returned as empty ([], {})
  • Number, String, and Boolean types may be returned as null
Clients should handle both null and empty values gracefully.