GSMA Camara Project Simple Edge Discovery API

Simple Edge Discovery API allows an application to discover the nearest Edge-Cloud zone for it to connect to, specifically the API will calculate the Edge Cloud Zone with the shortest network path to the application.

OpenAPI Specification

simple-edge-discovery-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Global System for Mobile Communications GSMA Camara Project Simple Edge Discovery
  version: 1.0.0
  x-camara-commonalities: 0.4.0
  description: >
    # Find the closest Edge Cloud Zone

    ---

    # Summary


    The Simple Edge Discovery API returns the name of the closest operator Edge

    Cloud Zone to a particular user device.


    # Purpose

    Network operators may host multiple Edge Cloud Zones in a

    given territory. Connecting your application to a server on the closest

    Edge Cloud Zone means packets travel the shortest distance between

    endpoints, typically resulting in the lowest round-trip latency. Note, the

    physical (GPS) location of a user device is not a reliable way to determine

    the closest Edge Cloud Zone, due to the way operator networks are routed -

    so the operator will calculate the Edge Cloud Zone with the

    _shortest network path_to the network-attached device identified in the API

    request.


    Once you have the name of the closest Edge Cloud Zone to the user device,

    you may:


    * connect the application client on the user device to your application

    server instance on that Edge Cloud Zone. Note: the address of that server

    instance is not part of the API response, but should be known in advance.

    * or, if you have no instance on that Edge Cloud Zone, you may wish to

    deploy one there.


    Note: the provider of the Edge Cloud Zone may be an operator, or a cloud

    provider working in partnership with the operator.


    # Usage


    The API may be called either by an application client hosted on a device

    attached to the operator network (i.e. phone, tablet), or by a server.


    There is a single API endpoint: `/edge-cloud-zones?filter=closest`. To call

    this endpoint, the API consumer must first obtain a valid OAuth2 token from

    the token endpoint, and pass it as an `Authorization` header in the API

    request.


    # Identifying the device


    The API returns the closest Edge Cloud Zone to a given device, so that

    device needs to be identifiable by the network. This can be achieved either

    by passing a device identifier in the request header, or, from the 3-legged

    access token where implemented by the operator.


    ## Passing a device identifier in the request header


    * If you call the API from a server, you must explicitly pass one or

    more device identifiers in the HTTP request header:
      * `IPv4-Address` or `IPv6-Address`. This is the public IP address of the
      user device: this
      can be obtained by an application hosted on that device calling a
      public IP address API (e.g. GET https://api.ipify.org?format=json)
      * If you provide an `IPv4-Address` or `IPv6-Address`: for certain
      operators you may be required to also provide a `Public-port` header.
      * `Phone-Number` . The international E.164 format (starting with country
      code), e.g. +4407123123456
      * `Network-Access-Identifier` (where available from the API host operator)

    * If you call the API from a device attached to the operator network, then

    you can attempt the request without passing device identifier(s) parameters

    in the request header. If that returns a 422 `UNIDENTIFIABLE_DEVICE`

    error then retry the request but this time include a device identifier.


    NOTE1: the network operator might support only a subset of these options.

    The API invoker can provide multiple identifiers to be compatible across

    different network operators. In this case the identifiers MUST belong to the

    same device.


    NOTE2: for the Commonalities release v0.4, we are enforcing that the

    `networkAccessIdentifier` is only part of the schema for future-proofing,
    and

    CAMARA does not currently allow its use. After the CAMARA meta-release work

    is concluded and the relevant issues are resolved, its use will need to be

    explicitly documented in the guidelines.


    ### Example requests:


    Examples for all API clients:

    ```
      GET /edge-cloud-zones?filter=closest HTTP/1.1
      Host: example.com
      Accept: application/json
      IPv4-Address: 84.125.93.10

      GET /edge-cloud-zones?filter=closest HTTP/1.1
      Host: example.com
      Accept: application/json
      Phone-Number: +441234567890
    ```

    Example where the network operator requires the public port to be passed:

    ```
      GET /edge-cloud-zones?filter=closest HTTP/1.1
      Host: example.com
      Accept: application/json
      IPv4-Address: 84.125.93.10
      Public-port: 1234
    ```


    Example where API client is on a network-attached device:

    ```
      GET /edge-cloud-zones?filter=closest HTTP/1.1
      Host: example.com
      Accept: application/json
    ```


    ## Identifying a device from the access token


    This specification defines the `device` identifying headers as optional in

    API requests, specifically in cases where the API is accessed using a

    3-legged access token and the device can be uniquely identified by the
    token.

    This approach simplifies API usage for API consumers by relying on the
    device

    information associated with the access token used to invoke the API.


    ### Handling of device information:


    #### Optional device identifying headers for 3-legged tokens:


    - When using a 3-legged access token, the device associated with the access
      token must be considered as the device for the API request. This means that
      a device  identifying header  is not required in the request, and if
      included it must identify the same device, therefore **it is recommended
      NOT to include it in these scenarios** to simplify the API usage and avoid
      additional validations.

    #### Validation mechanism:


    - The server will extract the device identification from the access token,
    if
      available.
    - If the API request additionally includes a `device`  identifying header
      when using a 3-legged access token, the API will validate that the device
      identifier provided matches the one associated with the access token.
    - If there is a mismatch, the API will respond with a
      403 `INVALID_TOKEN_CONTEXT` error, indicating that the device information
      in the request does not match the token.

    #### Error handling for unidentifiable devices:


    - If the `device`  identifying header is not included in the request and the
      device information cannot be derived from the 3-legged access token, nor
      inferred by the operator if the request is made directly from the client,
      the server will return a 422 `UNIDENTIFIABLE_DEVICE` error.

    #### Restrictions for tokens without an associated authenticated identifier:


    - For scenarios which do not have a single device identifier associated to
      the token during the authentication flow, e.g. 2-legged access tokens, a
      `device` identifying header MUST be provided in the API request. This
      ensures that the device identification is explicit and valid for each API
      call made with these tokens.

    # Responses


    ## Success


    A JSON object is returned containing an array with a single member object.

    This contains identifiers for the closest Edge Cloud Zone. The HTTP status

    code will be`200 OK`. An example response:


    ```

    [
      {
        "edgeCloudZoneId": "4gt555-6457-7890-d4he-1dc79f44gb66",
        "edgeCloudZoneName": "example zone name",
        "edgeCloudProvider": "example zone provider"
      }
    ]

    ```

    * `edgeCloudZoneId` is a UUID for the Edge Cloud Zone.

    * `edgeCloudZoneName` is the common name of the closest Edge Cloud Zone to

    the user device.

    * `edgeCloudProvider` is the name of the operator or cloud provider of

    the Edge Cloud Zone.


    ## Errors


    If the authentication token is not valid, a `401 UNAUTHENTICATED` error is

    returned.


    If the mobile subscription parameters contain a formatting error, a `400

    INVALID_ARGUMENT` error is returned.


    If the mobile subscription cannot be identified from the provided

    parameters, a `404 NOT_FOUND` error is returned.


    Any more general service failures will result in an error in the `5xx`range

    with an explanation.


    # Notes for Simple Edge Discovery API publishers


    If an `IPv4-Address` or `IPv6-Address` header parameter is provided then the

    operator should

    assume the request is coming from a developer's server rather than a device

    attached to the network. In which case the developer server is expected to

    have been provided with the device public IP address (e.g. by the

    application client on that device signalling it back to the server).


    If neither an `IPv4-Address`/`IPv6-Address` parameter, nor any other device

    identifier,  is

    provided in the API request header then the operator should assume the

    request is from a device attached to their network, and attempt to use the

    public IP source address to determine which packet gateway issued it (and

    hence the closest edge to that gateway).


    If no `IPv4-Address`/`IPv6-Address` header parameter is provided, but
    another

    device

    identifier(s) is provided, then the operator should assume the request is

    coming from a device attached to their network and should make use of one

    or both of the public IP source address (from the IP packet header) and the

    device identifier(s) provided in the HTTPS request header.


    Should your implementation require the `Port` value to be passed in addition

    to the `IP-Address`, please make that explicit in the documentation, and

    utilise the `GENERIC_400_MISSING_PORT` error if the `Port` header is
    omitted.


    # Authorization and authentication


    The "Camara Security and Interoperability Profile" provides details on how a

    client requests an access token. Please refer to Identify and Consent

    Management (https://github.com/camaraproject/IdentityAndConsentManagement/)

    for the released version of the Profile.


    Which specific authorization flows are to be used will be determined during

    onboarding process, happening between the API Client and the Telco Operator

    exposing the API, taking into account the declared purpose for accessing

    the API, while also being subject to the prevailing legal framework

    dictated by local legislation.


    It is important to remark that in cases where personal user data is

    processed by the API, and users can exercise their rights through

    mechanisms such as opt-in and/or opt-out, the use of 3-legged access tokens

    becomes mandatory. This measure ensures that the API remains in strict

    compliance with user privacy preferences and regulatory obligations,

    upholding the principles of transparency and user-centric data control.


    # Further info and support


    ---
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
externalDocs:
  description: Product documentation at CAMARA.
  url: https://github.com/camaraproject/EdgeCloud
servers:
  - url: '{apiRoot}/simple-edge-discovery/v1'
    variables:
      apiRoot:
        default: https://localhost:9091
        description: |
          API root, defined by the service provider, e.g.
          `api.example.com` or `api.example.com/somepath`
tags:
  - name: Discovery
    description: |
      Find the closest Edge Cloud Zone to the user device.
paths:
  /edge-cloud-zones:
    get:
      security:
        - openId:
            - simple-edge-discovery:edge-cloud-zones:read
      operationId: readClosestEdgeCloudZone
      parameters:
        - name: filter
          in: query
          required: true
          description: |
            Filter the Edge Cloud Zones according to the parameter value.
            For this API the only supported value is `closest`.
          schema:
            type: string
            enum:
              - closest
        - name: IPv4-Address
          in: header
          required: false
          description: >-
            The public IPv4 address allocated to the device by the network
            operator.
          example: 84.125.93.10
          schema:
            $ref: '#/components/schemas/SingleIpv4Addr'
        - name: Public-port
          in: header
          required: false
          description: >-
            The public TCP or UDP port allocated to the device by the network
            operator.
          example: 123
          schema:
            $ref: '#/components/schemas/Port'
        - name: IPv6-Address
          in: header
          required: false
          description: >-
            The public IPv6 address allocated to the device by the network
            operator.
          example: 2001:db8:85a3:8d3:1319:8a2e:370:7348
          schema:
            $ref: '#/components/schemas/DeviceIpv6Address'
        - name: Network-Access-Identifier
          in: header
          required: false
          description: |
            3GPP network access identifier for the subscription
            being used by the device.
          schema:
            $ref: '#/components/schemas/NetworkAccessIdentifier'
        - name: Phone-Number
          in: header
          example: '+441234567890'
          required: false
          description: |
            MSISDN in E.164 format (starting with country code) of
            the mobile subscription being used by the device. Optionally
            prefixed with '+'.
          schema:
            $ref: '#/components/schemas/PhoneNumber'
        - name: x-correlator
          in: header
          required: false
          description: |
            When the API Consumer includes the "x-correlator" header in the
            request, the API provider must include it in the response with
            the same value that was used in the request. Otherwise, it is
            optional to include the "x-correlator" header in the response with
             any valid value. Recommendation is to use UUID for values.
          schema:
            type: string
      responses:
        '200':
          description: |
            Successful response, returning the closest Edge Cloud
            Zone to the user device identified in the request header.
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EdgeCloudZones'
        '400':
          description: |
            Client eror - the required querystring was not provided
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorInfo'
              examples:
                InvalidQuerystring:
                  summary: Invalid querystring
                  description: >-
                    The 'filter' querystring parameter is missing or does not
                    have a value of 'closest'
                  value:
                    status: 400
                    code: INVALID_QUERYSTRING
                    message: 'Querystring must be provided: filter=closest'
        '401':
          $ref: '#/components/responses/Generic401'
        '403':
          $ref: '#/components/responses/Generic403'
        '404':
          $ref: '#/components/responses/Generic404'
        '406':
          $ref: '#/components/responses/Generic406'
        '422':
          $ref: '#/components/responses/Generic422'
        '429':
          $ref: '#/components/responses/Generic429'
        '500':
          $ref: '#/components/responses/Generic500'
        '501':
          $ref: '#/components/responses/Generic501'
        '502':
          $ref: '#/components/responses/Generic502'
        '503':
          $ref: '#/components/responses/Generic503'
        '504':
          $ref: '#/components/responses/Generic504'
      tags:
        - Discovery
      summary: |-
        Global System for Mobile Communications Returns the name of the Edge Cloud Zone closest to user device
        identified in the request.
      description: |
        On receiving this request, the network will return the name
        of the Edge Cloud Zone with the shortest network path to the end user
        device identified in the request.
components:
  securitySchemes:
    openId:
      description: OpenID Provider Configuration Information.
      type: openIdConnect
      openIdConnectUrl: .well-known/openid-configuration
  headers:
    x-correlator:
      description: |
        When the API Consumer includes the "x-correlator" header in the request,
         the API provider must include it in the response with the same value t
         hat was used in the request. Otherwise, it is optional to include the
         "x-correlator" header in the response with any valid value.
         Recommendation is to use UUID for values.
      required: false
      schema:
        type: string
  schemas:
    EdgeCloudZones:
      type: array
      items:
        $ref: '#/components/schemas/EdgeCloudZone'
      minItems: 1
      description: |
        A collection of Edge Cloud Zones. For this Simple Edge
        Discovery API the collection will have at most one member (the closest
        Edge Cloud Zone to the user device indicated in the request).
      additionalProperties: false
    EdgeCloudZone:
      type: object
      description: |
        An Edge Cloud Zone, uniquely identified by a combination
        of the value of the Edge Resource Name object and the value of the
        Provider object (the name of the cloud provider or operator hosting that
        edge cloud zone).
      properties:
        edgeCloudZoneId:
          $ref: '#/components/schemas/EdgeCloudZoneId'
        edgeCloudZoneName:
          $ref: '#/components/schemas/EdgeCloudZoneName'
        edgeCloudProvider:
          $ref: '#/components/schemas/EdgeCloudProvider'
    EdgeCloudZoneId:
      description: |
        Operator-issued UUID for the Edge Cloud Zone.
      type: string
      format: uuid
      additionalProperties: false
    EdgeCloudZoneName:
      description: |
        Edge Cloud Zone Name - the common name for the Edge Cloud Zone.
      type: string
      additionalProperties: false
    EdgeCloudProvider:
      description: |
        The company name of the Edge Cloud Zone provider.
      type: string
    ErrorInfo:
      type: object
      description: Error information
      required:
        - message
        - status
        - code
      properties:
        message:
          type: string
          description: A human readable description of what the event represents
        status:
          type: integer
          description: HTTP response status code
        code:
          type: string
          description: Friendly Code to describe the error
    PhoneNumber:
      description: >-
        A public identifier addressing a telephone subscription. In mobile
        networks it corresponds to the MSISDN (Mobile Station International
        Subscriber Directory Number). In order to be globally unique it has to
        be formatted in international format, according to E.164 standard,
        prefixed with '+'.
      type: string
      pattern: ^\+[1-9][0-9]{4,14}$
      example: '+123456789'
    NetworkAccessIdentifier:
      description: >-
        A public identifier addressing a subscription in a mobile network. In
        3GPP terminology, it corresponds to the GPSI formatted with the External
        Identifier ({Local Identifier}@{Domain Identifier}). Unlike the
        telephone number, the network access identifier is not subjected to
        portability ruling in force, and is individually managed by each
        operator.
      type: string
      example: [email protected]
    SingleIpv4Addr:
      description: A single IPv4 address with no subnet mask
      type: string
      format: ipv4
      example: 84.125.93.10
    DeviceIpv6Address:
      description: >-
        The device should be identified by the observed IPv6 address, or by any
        single IPv6 address from within the subnet allocated to the device
        (e.g.adding ::0 to the /64 prefix).
      type: string
      format: ipv6
      example: 2001:db8:85a3:8d3:1319:8a2e:370:7344
    Port:
      description: TCP or UDP port number
      type: integer
      minimum: 0
      maximum: 65535
  responses:
    Generic401:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_401_UNAUTHENTICATED:
              description: Request cannot be authenticated
              value:
                status: 401
                code: UNAUTHENTICATED
                message: >-
                  Request not authenticated due to missing, invalid, or expired
                  credentials.
            GENERIC_401_AUTHENTICATION_REQUIRED:
              description: New authentication is needed, authentication is no longer valid
              value:
                status: 401
                code: AUTHENTICATION_REQUIRED
                message: New authentication is required.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic403:
      description: Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_403_PERMISSION_DENIED:
              description: >-
                Permission denied. OAuth2 token access does not have the
                required scope or when the user fails operational security
              value:
                status: 403
                code: PERMISSION_DENIED
                message: >-
                  Client does not have sufficient permissions to perform this
                  action.
            'GENERIC_403_INVALID_TOKEN_CONTEXT:':
              description: >-
                Reflect some inconsistency between information in some field of
                the API and the related OAuth2 Token
              value:
                status: 403
                code: INVALID_TOKEN_CONTEXT
                message: '{{field}} is not consistent with access token.'
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic404:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_404_NOT_FOUND:
              description: Resource is not found
              value:
                status: 404
                code: NOT_FOUND
                message: The specified resource is not found.
            GENERIC_404_DEVICE_NOT_FOUND:
              description: Device identifier not found
              value:
                status: 404
                code: DEVICE_NOT_FOUND
                message: Device identifier not found.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic406:
      description: Not Acceptable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_406_NOT_ACCEPTABLE:
              description: >
                API Server does not accept the media type (`Accept-*` header)
                indicated by API client
              value:
                status: 406
                code: NOT_ACCEPTABLE
                message: >
                  The server cannot produce a response matching the content
                  requested by the client

                  through `Accept-*` headers.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic422:
      description: Unprocessable Content
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_422_DEVICE_IDENTIFIERS_MISMATCH:
              description: >-
                Inconsistency between device identifiers not pointing to the
                same device
              value:
                status: 422
                code: DEVICE_IDENTIFIERS_MISMATCH
                message: Provided device identifiers are not consistent.
            GENERIC_422_DEVICE_NOT_APPLICABLE:
              description: Service is not available for the provided device
              value:
                status: 422
                code: DEVICE_NOT_APPLICABLE
                message: The Service is not available for the provided device.
            GENERIC_422_UNIDENTIFIABLE_DEVICE:
              description: >-
                The device identifier is not included in the request and the
                device information cannot be derived from the 3-legged access
                token
              value:
                status: 422
                code: UNIDENTIFIABLE_DEVICE
                message: The device cannot be identified.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic429:
      description: Too Many Requests
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_429_QUOTA_EXCEEDED:
              description: Request is rejected due to exceeding a business quota limit
              value:
                status: 429
                code: QUOTA_EXCEEDED
                message: Either out of resource quota or reaching rate limiting.
            GENERIC_429_TOO_MANY_REQUESTS:
              description: API Server request limit is overpassed
              value:
                status: 429
                code: TOO_MANY_REQUESTS
                message: Either out of resource quota or reaching rate limiting.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic500:
      description: Internal Server Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_500_INTERNAL:
              description: Problem in Server side. Regular Server Exception
              value:
                status: 500
                code: INTERNAL
                message: Unknown server error. Typically a server bug.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic501:
      description: Not Implemented
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_501_NOT_IMPLEMENTED:
              description: >-
                Service not implemented. The use of this code should be avoided
                as far as possible to get the objective to reach aligned
                implementations
              value:
                status: 501
                code: NOT_IMPLEMENTED
                message: This functionality is not implemented yet.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic502:
      description: Bad Gateway
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_502_BAD_GATEWAY:
              description: >-
                Internal routing problem in the Server side that blocks to
                manage the service properly
              value:
                status: 502
                code: BAD_GATEWAY
                message: An upstream internal service cannot be reached.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic503:
      description: Service Unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_503_UNAVAILABLE:
              description: >-
                Service is not available. Temporary situation usually related to
                maintenance process in the server side
              value:
                status: 503
                code: UNAVAILABLE
                message: Service Unavailable.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
    Generic504:
      description: Gateway Timeout
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_504_TIMEOUT:
              description: API Server Timeout
              value:
                status: 504
                code: TIMEOUT
                message: Request timeout exceeded.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'