> ## Documentation Index
> Fetch the complete documentation index at: https://team.k0labs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Common Structures

> API conventions, data types, and common patterns

> 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

```typescript theme={null}
// 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

```json theme={null}
{
  "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

```json theme={null}
{
  "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

| Field       | Type   | Description                                        |
| ----------- | ------ | -------------------------------------------------- |
| `requestId` | string | Unique request identifier for log correlation      |
| `timestamp` | string | ISO 8601 timestamp (UTC) for distributed debugging |

### Extended Meta Types

Success responses can extend meta with additional context:

**Pagination Meta:**

```json theme={null}
{
  "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:**

```json theme={null}
{
  "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

| Resource     | Prefix   | Example                              |
| ------------ | -------- | ------------------------------------ |
| Organization | `org_`   | `org_8TcVx2WkZddNmK3Pt9JwX7BzWrLM`   |
| Server       | `srv_`   | `srv_3KpQm9WnXccFjH2Ls8DkT6VzRqYU`   |
| Cluster      | `cls_`   | `cls_6NZtkvWLBbbmHfPi7L6oz7KZpqET`   |
| Stack        | `stk_`   | `stk_5MfRp4WjYbbHmG8Nt2LvS9CxPqZK`   |
| Workflow Run | `run_`   | `run_7NhTq6WlAbbKmF5Rt3MxU8DzSqWJ`   |
| Pool         | `pool_`  | `pool_2LgPn8WmXccGjE7Mt4KwV9BySrTL`  |
| Allocation   | `alloc_` | `alloc_9QjSr3WnZddMmH6Pt5LxW2CzUrYK` |
| API Key      | `key_`   | `key_4KfQm7WkYccJmG3Nt8MvX9BzSqWL`   |
| Event        | `evt_`   | `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

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

### Field Names

| Rule                      | Example                               |
| ------------------------- | ------------------------------------- |
| camelCase                 | `createdAt`, `nodeCount`              |
| Suffix IDs with `Id`      | `clusterId`, `organizationId`         |
| Past tense for timestamps | `createdAt`, `updatedAt`, `deletedAt` |

## Dates and Timestamps

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

### Common Fields

| Field       | Description                               |
| ----------- | ----------------------------------------- |
| `createdAt` | When the object was created               |
| `updatedAt` | When the object was last updated          |
| `deletedAt` | When the object was deleted (soft delete) |

### Example

```json theme={null}
{
  "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:

| Method   | Purpose                             |
| -------- | ----------------------------------- |
| `GET`    | Retrieve resources (read-only)      |
| `POST`   | Create new resources                |
| `PATCH`  | Update existing resources (partial) |
| `DELETE` | Delete resources                    |

### Content Type

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

### Example Request

```bash theme={null}
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:

```bash theme={null}
GET /v1/region/global/infrastructure/servers?limit=50&cursor=srv_abc123
```

**Response:**

```json theme={null}
{
  "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:

```bash theme={null}
GET /v1/region/global/infrastructure/servers?limit=50&offset=100
```

**Response:**

```json theme={null}
{
  "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

| Parameter | Description                        | Default |
| --------- | ---------------------------------- | ------- |
| `limit`   | Number of items per page (max 100) | 25      |
| `offset`  | Skip this many items               | 0       |
| `cursor`  | Opaque cursor for next page        | -       |

## Filtering

You can filter resources by most attributes using query parameters:

### Simple Filter

```bash theme={null}
GET /v1/region/global/infrastructure/servers?state=available
```

### Multiple Values

```bash theme={null}
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

```bash theme={null}
GET /v1/region/global/infrastructure/servers?sort=name
```

### Sort Descending

Use `-` prefix for descending:

```bash theme={null}
GET /v1/region/global/infrastructure/servers?sort=-createdAt
```

### Multiple Sort Fields

```bash theme={null}
GET /v1/region/global/infrastructure/servers?sort=state,-createdAt
```

## Field Design Rules

### Use Objects Over Primitives

Always wrap values that might grow into objects:

```typescript theme={null}
// ✅ 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:

```typescript theme={null}
// ✅ 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:

```json theme={null}
// ✅ 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.
