For each specified service a clause to a normative Annex should be provided containing the OpenAPI definitions according to OpenAPI Specification  for the service. The specifications should state that content of this normative annex takes precedence when being discrepant to other parts of the specification with respect to the encoding of information elements and methods.
The TS Skeleton Template as provided in Annex A should be used as a starting point when drafting 5GC SBI API specifications.
Common procedures, HTTP extensions and error handling applicable to several 5GC SBI API specifications should be defined in TS 29.500 and should be referenced from individual 5GC SBI API specifications.
Common data types applicable to several 5GC SBI API specifications should be defined in TS 29.571 and should be referenced from individual 5GC SBI API specifications.
5GC SBI API specifications should apply a protocol design framework as follows:
REST-style service operations should implement the Level 2 of the Richardson maturity model, with standard HTTP methods, whenever it is a good match for the style of interaction to model, e.g. service operations that can naturally map to one of the standard methods (CRUD operations), this should be the preferred modelling attempt;
service operations may use custom API operations (RPC-style interaction), when it is seen a better fit for the style of interaction to model, e.g. non-CRUD service operations;
it is possible to mix REST-style operations and RPC-style operations in the same API.
API version numbers shall consist of at least 3 fields, following a MAJOR.MINOR.PATCH pattern according to the Semantic Versioning Specification  with exceptions for 3GPP Releases under development. A fourth DRAFT field is added to denote an OpenAPI version under development i.e., prior to the freeze of the corresponding OpenAPI description for a given 3GPP Release. Optionally, additional fields can be added after those fields based on operator policy.
The 1st field (MAJOR), the 2nd field (MINOR), and the 3rd field (PATCH) shall contain unsigned integer numbers.
During the development of an API (i.e. before the freeze of a given 3GPP Release), the 4th field is called DRAFT, and it shall have the format "alpha-n", where "n" is an unsigned integer number.
After the freeze of a 3GPP Release, the optional 4th field shall not be considered as DRAFT and it may contain any string, with a format other than "alpha-n"; any additional optional field(s), when present, may contain any string.
The fields shall be separated by ".".
The first version of a new API under development shall obtain the version number "1.0.0.alpha-1". At the first publication of the 3GPP Technical Specification defining the API after the OpenAPI freeze of the first 3GPP Release that contains the API, the version number of the API shall be set to "1.0.0".
When a new version of the 3GPP TS containing OpenAPI file(s) is published, the fields of the corresponding API version number(s) shall be incremented according to the following rules:
1st Field (MAJOR):
This numerical field shall be incremented when:
there are one or more backward incompatible changes to the API after the OpenAPI freeze for a given 3GPP Release; and
there are the first backward incompatible change(s) to the existing API with respect to the latest version in the previous 3GPP Release while a 3GPP Release is under development (i.e. prior to the OpenAPI freeze for a given 3GPP Release).
Assuming that 3GPP Rel-16 under development contains API version "1.1.0.alpha-2", and a backward incompatible change with respect to the latest version in the previous 3GPP Release is applied to that API before the OpenAPI freeze, the new Rel-16 API version is "2.0.0.alpha-1".
If a backward incompatible change needs to be applied to several 3GPP Releases the following applies:
If the 3GPP Releases contain different MAJOR versions of the same API, a new MAJOR API version shall be assigned to each 3GPP Release in the order of those 3GPP Releases in such a manner that the lowest of those 3GPP Releases shall obtain the first unassigned MAJOR version value.
Assuming that 3GPP Rel-15 contains API version "1.0.0", and Rel-16 contains API version "2.0.0", and that the same backward incompatible change is applied to that API in both Releases, the new Rel-15 API version is "3.0.0" and the new Rel-16 API version is "4.0.0".
If the 3GPP Releases contain the same MAJOR version but different MINOR versions of the same API, a single new MAJOR API version value shall be assigned for all those 3GPP Releases, unless other backward incompatible changes only applied to some of those Releases require the creation of separate MAJOR versions.
Assuming that 3GPP Rel-15 and Rel-16 contain API version "1.0.0", and Rel-17 contains API version "1.2.0", and that the same backward incompatible change is applied to that API in all 3GPP Releases, the new 3GPP Rel-15 and Rel-16 API version is "2.0.0" and the new 3GPP Rel-17 API version is "2.2.0".
If the 3GPP Releases contain the same API versions, a single new API version shall be assigned for all those 3GPP Releases, unless other changes only applied to some of those Releases require the creation of separate versions.
Assuming that 3GPP Rel-15 and 3GPP Rel-16 contain API version "1.0.0", and that only the same backward incompatible change is applied to that API in both 3GPP Releases, the new 3GPP Rel-15 and Rel-16 API version is "2.0.0".
Assuming that 3GPP Rel-15 and Rel-16 contain API version "1.0.0", and that the same backward incompatible change is applied to that API in both Releases and an additional backward compatible change is applied in 3GPP Rel-16, the new 3GPP Rel-15 API version is "2.0.0", and the 3GPP Rel-16 API version is "2.1.0".
Assuming that 3GPP Rel-15 and Rel-16 contain API version "1.0.0", and that the same backward incompatible change is applied to that API in both Releases and an additional backward incompatible change is applied in 3GPP Rel-16, the new 3GPP Rel-15 API version is "2.0.0", and the 3GPP Rel-16 API version is "3.0.0".
2nd Field (MINOR):
This numerical field shall be incremented when:
there are the first one or more backward compatible changes not corresponding to changes to earlier 3GPP Releases (i.e. changes introduced by 3GPP CR with other categories than "mirror") to the same API in a given 3GPP Release without any prior backward incompatible changes in that Release. If the same 1st field (MAJOR) and the 2nd field (MINOR) are assigned to n previous 3GPP Releases, a MINOR version number shall be reserved for each intermediate 3GPP Release for possible subsequent changes in that Release and the MINOR version number shall be incremented by n; and
Assuming that 3GPP Rel-15 and Rel-16 contain API version "1.0.0" (because there were no changes to the API in Rel-16), and in Rel-17 the first backward compatible new feature is added before the OpenAPI freeze, the API version "1.2.0.alpha-1" is assigned to Rel-17.
there are one or more subsequent backward compatible additions of features not corresponding to changes to previous 3GPP Releases to the API in a frozen 3GPP Release before a higher MINOR number has been allocated for the same MAJOR version (for a subsequent Release).
This field shall be reset to "0" if the 1st field (MAJOR) is changed, unless a backward incompatible change needs to be applied to several 3GPP Releases that already contain the same MAJOR but different MINOR API versions. In that case a single new major API version is assigned, and for each such 3GPP Release with an own MINOR version, a new MINOR version shall be assigned, starting with MINOR version "0" for the lowest such Release, and reserving a MINOR version number for each intermediate Release without an own MINOR version. (see Example 3)
Assuming that an API was introduced with version "1.0.0" in Rel-15, and that the Rel-16 version is "1.1.0.alpha-5" because the OpenAPI is not yet frozen in Rel-16, and that a new backward compatible Rel-17 feature is added, the Rel-17 API version is "1.2.0.alpha-1".
3rd Field (PATCH):
This numerical field shall be incremented:
if the changes are only one or more backward-compatible corrections (but no changes requiring an update of the 1st field (MAJOR) or of the 2nd field (MINOR) are made to the API after the OpenAPI freeze of a 3GPP Release; and
if one or more backward compatible additions of features, but no changes requiring an update of the 1st field (MAJOR) or of the 2nd field (MINOR), are made to the API after the OpenAPI freeze of a 3GPP Release and after the assignment of a MINOR version to a higher 3GPP Release.
This field shall be reset to "0" if the 1st field (MAJOR) or 2nd field (MINOR) is changed.
Before the OpenAPI freeze of a 3GPP Release, the 4th field (DRAFT) shall be supplied as follows:
When the 1st or 2nd field is incremented before the OpenAPI freeze of a 3GPP Release, this field shall obtain the value "alpha-1".
The numerical value "n" within the field value "alpha-n" shall be incremented if one or more subsequent changes are made to the API under development.
After the OpenAPI freeze of a 3GPP Release, the 4th field is not managed anymore by 3GPP.
After the OpenAPI freeze of a 3GPP Release, additional fields may be supplied based on operator policy after the 3rd field. The rules for setting, or incrementing, such fields are out of the scope of 3GPP.
If no change is applied to an API in a new published TS version, the API version number shall not be incremented unless the draft field needs to be removed at OpenAPI freeze. This also applies if the TS is published in a new 3GPP Release.
The API version shall be indicated in the resource URI of every API, as described in clause 4.4.1.
The API version shall be indicated as the concatenation of the letter "v" and the 1st field of the API version number.
The other fields shall not be included in the resource URI.
The full API version number (i.e., containing all the fields) shall be visible in the OpenAPI specifications, in the "version" subfield of the "info" field, as described in clause 5.3.3.
There is no one-to-one mapping between an API version number and the version number of the 3GPP Technical Specification defining this API.
A 3GPP Technical Specification specifies one or more APIs, which may have different versions.
A change in the 3rd field of a 3GPP TS version number (i.e. an editorial change) should not lead to a change in the version number of the APIs specified in the 3GPP TS.
A change in the 1st and 2nd fields of the 3GPP TS version number is likely to lead to at least a change in the minor version number of the APIs specified in the 3GPP TS.
If version 15.4.1 of a 3GPP TS contains version "1.1.1" of API A, B and C, and a version 16.0.0 of this 3GPP TS is derived from version 15.4.1, TS version 16.0.0 can contain version "1.2.0.alpha-1" of API A (if all changes made are backward compatible), version "2.0.0.alpha-1" of API B (if some changes are no backward compatible) and version "1.1.1" of API C (if no changes were made).
The 3GPP TS defining the API is indicated in the OpenAPI specification of the API, as described in clause 5.3.4.
The NF service consumer may discover the API version(s) supported by an NF service producer using the following mechanisms:
NRF query: The NF service consumer may retrieve from the NRF the NF profile of a given NF Instance. This NF profile contains the full version number(s) of the API(s) supported by an NF Service Instance, as described in the clause 188.8.131.52.4 of TS 29.510 and the planned retirement date.
NF profile change notifications: The NF service consumer may subscribe for NF status change notifications with the NRF as specified in clause 184.108.40.206 of TS 29.510. The NRF shall notify as specified in clause 220.127.116.11 of TS 29.510, any change to the NF profile which may include updated NF service profile containing the current list of NF services and their versions supported by the NF.
When a new major version is created, the NF service producer shall continue supporting at least the previous major version until a retirement date unless all API versions (except for draft API versions published prior to the OpenAPI freeze) with that previous major version are withdrawn (see clause 18.104.22.168); this enables NF service consumers to migrate to the new version. After expiration of the retirement date, the old major version should be deprecated. The retirement date of an old major version supported by a NF service instance may be updated in the NF profile in the NRF.
If it is discovered that one or several previous API versions are not providing the basic mandatory functionality of an API due to severe functional or encoding deficits (for instance, there is no or very limited interoperability between the NF service consumer and NF service producer when such an API version is used, or the API is hardly implementable because of severe deficits in the OpenAPI file that cannot easily be fixed by implementors in an interoperable manner), those API versions shall be listed as withdrawn in subsequent versions of the TS defining the corresponding API; any withdrawn API versions from the same or previous 3GPP releases shall be listed. API versions published before the OpenAPI freeze of the corresponding 3GPP Release, i.e. with a 4th Field (DRAFT) as part of the version number, shall not be withdrawn.
Withdrawn API versions should not be deployed.
Resources are either individual resources, or structured resources that can contain child resources. It is recommended to design each resource following one of the archetypes provided in the Annex C.
A URI uniquely identifies a resource. In the 5GC SBI APIs, when a resource URI is an absolute URI, its structure shall be specified as follows:
"apiRoot" shall be a concatenation of the following parts:
scheme ("http" or "https")
the fixed string "://"
authority (host and optional port) as defined in RFC 3986
an optional deployment-specific string (API prefix) that starts with a "/" character.
"apiName" shall define the name of the API.
"apiVersion" shall indicate the 1st Field (MAJOR) of the version of the API. See also clause 22.214.171.124.
While "apiRoot", "apiName" and "apiVersion" together define the API URI of the corresponding API, each "apiSpecificResourceUriPart" defines a resource URI of the API relative to the API URI.
Custom operations can also be associated with the service instead of a resource. The URI of a custom operation which is not associated with a resource shall have the following structure:
In the above URI structures, "apiRoot", "apiName", "apiVersion" and "apiSpecificResourceUriPart" are as defined in clause 4.4.1 and "custOpName" represents the name of the custom operation as defined in clause 126.96.36.199.
The purpose of the callback URI is to enable NF service consumer to provide the URI to be used by an NF Service Producer to send notification or callback requests.
The callback URI shall be in the form of an absolute URI as defined in clause 4.3 of IETF RFC 3986, including an authority, and excluding any query component, any fragment component and any userinfo subcomponent.
Therefore, callback URI consists of the following components, specified with ABNF syntax (see RFC 5234):
URI = scheme ":" "//" host [ ":" port ] / path
Where 'host' is either an FQDN or an IP address and the 'path' is a path to an NF consumer resource.
A resource representation is a serialization of the resource state in a particular content format. It's included in the data frame of an HTTP/2 request or response. Representation header fields provide metadata about the representation. When a message includes a data frame, the representation data enclosed in the data frame. HTTP/2 reuses the definition of Representation header as HTTP 1.1 in RFC 7231. Content-type field in HTTP/2 header performs as representation header fields and describes the representation data that would have been enclosed in the data frame, e.g. if content-type is application/json, resource representation in data frame is serialized in JSON format.
Server supports the content format of the representation received in the data frame of the request and returns the "200 OK" response code.
RFC 7231 provides a mechanism to negotiate the content format of a representation.
In HTTP/2 requests and responses, the "Content-Type" HTTP/2 header field is used to signal the format of the actual representation included in the data frame. If the format of the representation in an HTTP/2 request is not supported by the server, it responds with the "415 Unsupported Media Type" response code.
For GET method, the "Accept" HTTP header of the HTTP/2 request signals the content formats that a client supports. If the server cannot provide any of the accepted formats, it returns the "406 Not Acceptable" response code.