Name: Stability levels markers
Status: approved
Created: 2025-05-19
Updated: 2025-05-19

Stability levels markers (#181)

Kong APIs should use stability levels markers to indicate the stability of a field or an API.
This is important for developers to understand the level of support and stability they can expect from a given field or API.

Guidance

Kong uses custom annotations in OAS files to communicate an API's visibility, stability and where in the development lifecycle it is.

The following stability levels exist:

  • If x-unstable, the functionality should be considered unstable.
  • If x-internal, the functionality is internal to Kong and should not be used by customers, it should therefore not be exposed in public documentation.
  • If x-internal and x-unstable are both present, the functionality is considered internal and unstable, this is most often used for feature currently in development.
  • If x-private, the functionality is private and should not be exposed by Gateways. An example of this are metadata endpoints.
    In the absence of a specific stability level, the API is considered stable.
    For deprecation, the deprecated: true field from the openAPI specification must be used.

These annotations can be applied to either endpoints (alongside operationId) or to schemas in components.schemas.
If applied to a schema, the schema and any references to that schema can be removed from the rendered file.
This allows adding new fields to existing endpoints without publishing them publicly whilst the functionality is in development.
The x-private marker should not used for fields or schemas to avoid confusion between x-internal and x-private.

This spec was extracted from: platform api.
Also refer to Google AIP-181 when thinking about API stability levels.

Here's a common maturity lifecycle for APIs:

  • Development: x-unstable and x-internal. The API is not ready for public use as developers are still able to do breaking changes, internal use-cases should mostly be for testing and early integration.
  • Stabilizing: x-internal. The API is available for internal usage. Breaking changes should be avoided, but may be made by working with any internal consumers.
  • Public: No annotations. The API is stable and ready for public use.
  • Deprecated (maybe): deprecated: true. The API is deprecated and will be removed in the future. Users should stop using it and migrate to a different API.

Examples

Endpoint

openapi: 3.0.3
info:
title: My API
version: 0.0.1
paths:
/blobs:
get:
x-unstable: true
x-internal: true
operationId: list-blobs
responses:
"200":
description: OK
content:
application/json:
schema:
type: array
items:
type: string

Parameter

openapi: 3.0.3
info:
title: My API
version: 0.0.1
paths:
/blobs:
get:
parameters:
- name: expanded
in: query
x-internal: true
operationId: list-blobs
responses:
"200":
description: OK
content:
application/json:
schema:
type: array
items:
type: string

New fields on shared schemas

If you want to add a new property to an endpoint that uses a shared schema, you can add an x-property-annotations entry at the same level as properties within the schema:

MyResource:
type: object
x-property-annotations:
my_property: [x-unstable, x-internal]
properties:
id:
type: string
something:
type: string
my_property: # This should not be shown in public versions of the API
type: string

Enums

You can have dev/internal only enums too using x-enum-dev and x-enum-internal.

All values must be placed in enum, and anything in x-enum-dev will be present in the dev spec and removed from the internal and public specs. Anything in x-enum-internal will be present in the dev and internal specs, and removed from public.

For example:

enum:
- "cat"
- "dog"
- "none"
- "hamster"
- "giraffe"
x-enum-dev:
- "hamster"
x-enum-internal:
- "giraffe"

Dev output:

enum:
- "cat"
- "dog"
- "none"
- "hamster"
- "giraffe"

Internal output:

enum:
- "cat"
- "dog"
- "none"
- "giraffe"

Public output:

enum:
- "cat"
- "dog"
- "none"