GSMA Open Gateway Simple Edge Discovery API

CAMARA Simple Edge Discovery API as published on the GSMA Open Gateway developer portal. Returns the closest edge cloud zone to a given device so an application can route traffic to the lowest-latency multi-access edge computing deployment. OpenAPI 3.0.3, version 1.0.0, 1 path(s) and 1 operation(s); authorization is OpenID Connect (openIdConnect security scheme) with per-operation CAMARA scopes.

OpenAPI Specification

gsma-open-gateway-simple-edge-discovery-openapi.yml Raw ↑
---
openapi: 3.0.3
info:
 title: 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: |
    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: "123456789@domain.com"

  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"