Catalog: zones, versions, and machine tiers¶
GET /v1/catalog is the product list for a zone: which Kubernetes versions you may request, which machine tier ids you send as node_pools[].size, and the name/pool limits the create form enforces.
Who can do this: member or super_admin on the resolved organization.
Always call the catalog (or use the console wizard, which calls it for you) before POST /v1/public/clusters. Unknown kubernetes_version or size values return 400.
Request¶
curl -sS "https://dks-api.apps.door.cloud/v1/catalog?zone=abidjan" \
-H "Authorization: Bearer $DOOR_TOKEN" \
-H "X-Door-Organization: acme"
| Query | Type | Default | Notes |
|---|---|---|---|
zone | string | abidjan | Unknown zone → 400 unknown zone='…'. |
Organization uses the same resolution rules as other reads (?organization= → X-Door-Organization → preferred org). 401 / 403 / 400 behave as on cluster list.
Response shape¶
schema_version is catalog.public.v1. Extra provider fields (size backing names, images) are omitted on purpose.
zone¶
| Field | Type | Abidjan today |
|---|---|---|
id | string | abidjan |
display_name | string | Abidjan |
region_label | string or null | Côte d'Ivoire |
kubernetes_versions[]¶
Sorted newest-first. Each item:
| Field | Type | Meaning |
|---|---|---|
id | string | Value you send as kubernetes_version (include the v). |
label | string | Display label. |
recommended | boolean | Preferred version for new clusters. |
support_channel | string or null | For example stable. |
Abidjan currently publishes:
id | label | recommended | support_channel |
|---|---|---|---|
v1.32.4 | 1.32.4 | true | stable |
control_plane_options[] and active_control_plane_option_id¶
The catalog lists Door's control-plane offerings for the zone (id, display_name, description, recommended). active_control_plane_option_id is the zone default. Door may assign a different option to your organization. Ignore any other fields on these objects.
You do not pick a control plane on create. POST /v1/public/clusters has no control-plane field. Sending one is 422 (extra_forbidden). Treat these catalog fields as information, not as request parameters.
machine_tiers[]¶
Each tier:
| Field | Type | Meaning |
|---|---|---|
id | string | Value you send as node_pools[].size. |
display_name | string | Short label in pickers. |
description | string or null | Human summary. |
spec.vcpu | int | vCPU per node. |
spec.memory_gib | int | Memory (GiB) per node. |
spec.disk_gib | int | Worker root disk (GiB). This becomes root_volume_size_gib on the pool. |
recommended | boolean | Suggested default in the wizard. |
Abidjan public tiers (disk is provisioned to match spec.disk_gib):
id | Display | vCPU | RAM (GiB) | Disk (GiB) | Recommended |
|---|---|---|---|---|---|
dks.c5.large | c5.large | 2 | 4 | 50 | no |
dks.m5.large | m5.large | 2 | 8 | 60 | no |
dks.c5.xlarge | c5.xlarge | 4 | 8 | 80 | yes |
dks.m5.xlarge | m5.xlarge | 4 | 16 | 120 | no |
dks.c5.2xlarge | c5.2xlarge | 8 | 16 | 160 | no |
c5 is compute-oriented (about 1 vCPU : 2 GiB). m5 is general-purpose (about 1 vCPU : 4 GiB). Use only these ids on the public API. A raw provider size is rejected with 400; the error lists public tier ids only.
constraints¶
Hardcoded on the catalog endpoint (same RFC1123 pattern as cluster and pool names in the request schema):
{
"cluster_name": {
"pattern": "^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$",
"min_length": 1,
"max_length": 63
},
"node_pools": {
"min": 1,
"max": 20,
"min_nodes_per_pool": 1,
"max_nodes_per_pool": 200
}
}
| Rule | What it means |
|---|---|
| Cluster name | Lowercase DNS label: a-z, 0-9, hyphens; no leading/trailing hyphen; 1–63 characters. Same rule for pool names, Elastic IP names, and cluster tags. |
| Pools per cluster | At least 1, at most 20 (node_pools min_length/max_length on create). |
| Nodes per pool (form) | Catalog publishes 1–200. The create/add schema allows count 0–200; count=0 is valid only with auto_scale=true (and then count must lie in [min_nodes, max_nodes]; omitted min_nodes defaults to 1). |
A name that fails the pattern is 422. A cluster with zero pools is 422 (schema) or 400 (empty list after validation).
defaults¶
Server-chosen values used when you omit the field on create:
| Field | Current platform default | Meaning |
|---|---|---|
network_mode | intranet | Application Elastic IPs are private / VPN-reachable. internet is Internet-routed. Immutable after create. |
exposure_mode | public | Kubernetes API hostname is Internet-reachable. private is VPN/network only. You can change exposure later. |
These follow platform settings. Seed your form from the catalog rather than hardcoding.
copy¶
Optional string map (copy on the wire) for UI blurbs. Often empty. Render only if present.
pricing¶
Optional zone tariff card (zone_id, label, currency, hours_per_day, hours_per_month, items[] with id, label, unit, unit_price, optional day/month list prices). null when unpublished or unavailable. The rest of the catalog still succeeds. For commercial terms, contact your Door account team — do not assume list prices from an empty card.
How tiers map to node_pools[].size¶
On create and on add-pool, each pool must look like:
size is the catalog machine_tiers[].id. The cluster response echoes the same public id on node_pools[].size. You cannot change size with PATCH; add a new pool and delete the old one. See Node pools.
Worker capacity on the cluster (total_vcpu, total_memory_gib, total_volume_gib) is the sum over pools of (tier spec × effective node count). Autoscaling pools use max_nodes for that total.
Console and Maya¶
Console: /dks/clusters/new loads this catalog for zone, version, and size pickers.
Maya: “Show the Abidjan catalog: Kubernetes versions and machine tiers.” Then create with a real id from that list.
Example: full Abidjan-shaped body¶
{
"schema_version": "catalog.public.v1",
"zone": {
"id": "abidjan",
"display_name": "Abidjan",
"region_label": "Côte d'Ivoire"
},
"kubernetes_versions": [
{
"id": "v1.32.4",
"label": "1.32.4",
"recommended": true,
"support_channel": "stable"
}
],
"control_plane_options": [
{
"id": "production",
"display_name": "Production",
"description": "Suitable for critical and always-on applications.",
"recommended": true
},
{
"id": "development",
"display_name": "Development",
"description": "Lower cost, faster provisioning. Not for production.",
"recommended": false
}
],
"active_control_plane_option_id": "development",
"machine_tiers": [
{
"id": "dks.c5.large",
"display_name": "c5.large",
"description": "Compute-optimized · 2 vCPU / 4 GiB · dev & small services.",
"spec": { "vcpu": 2, "memory_gib": 4, "disk_gib": 50 },
"recommended": false
},
{
"id": "dks.c5.xlarge",
"display_name": "c5.xlarge",
"description": "Compute-optimized · 4 vCPU / 8 GiB · general web/API workloads.",
"spec": { "vcpu": 4, "memory_gib": 8, "disk_gib": 80 },
"recommended": true
}
],
"constraints": {
"cluster_name": {
"pattern": "^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$",
"min_length": 1,
"max_length": 63
},
"node_pools": {
"min": 1,
"max": 20,
"min_nodes_per_pool": 1,
"max_nodes_per_pool": 200
}
},
"defaults": {
"network_mode": "intranet",
"exposure_mode": "public"
},
"copy": {},
"pricing": null
}
Do not copy control_plane_options into a cluster create body. The create wizard shows an estimated price next to each machine type; commercial terms still come from your Door account team when pricing is null.