openapi: 3.0.3
info:
  version: 1.0.5
  title: "Sim Specification Management API"
  description: |
    #### Copyright
    © Aeris Communications, Inc. 2026. All rights reserved. No part of this document may be reproduced in any form without the written permission of the copyright owner.

    #### Disclaimer

    The contents of this document are subject to revision without notice due to continued progress in methodology, design and manufacturing.
    Aeris shall have no liability for any error or damage of any kind resulting from the use of this document.

    #### Trademark List

    All trademarks mentioned herein are the property of their respective owners.
    These are shown in the document Trademark Information.

    # Introduction

    This document describes the IoTA BSS SIM Specification API that provides CRUD operations for
    SIM specifications and a possibility to retrieve file share information.
    
    This API is rate-limited, exact limits are available in response message headers.

     # Important

     API audience must be prepared for compatible API extensions:

     - Be tolerant with unknown fields in the payload (see also Fowler’s \"TolerantReader\" post), i.e. ignore new fields but do not eliminate them from payload if needed
     for subsequent PUT requests.
     - Be prepared that "x-extensible-enum" return parameter may deliver new values. Either be agnostic or provide default behavior for unknown values.
     - Be prepared to handle HTTP status codes not explicitly specified in endpoint definitions.
     - Follow the  redirect when the server returns HTTP status 301 Moved Permanently.

     # Deprecation

     API deprecation will be reflected in the OpenAPI definition.
     If a method on a path, a whole path or even a whole API endpoint (multiple paths) should be deprecated, they will be marked as deprecated.
     During deprecation phase, a Warning header (see RFC 7234 - Warning header) field will be added in the response. The warn-code will be 299 and the warn-text will inform about what is deprecated and when it will be completely removed.

     API audience should not start using a deprecated API.

     API audience is encouraged to monitor for Warning header.

     #

    ## Scope

    This document covers the following topics:

    — An overview of the API

    — A detailed description of all operations offered by the API

    ## Prerequisites
    In this document, it is assumed that the user is familiar with the following:

    — Java Script Object Notation (JSON)

    — Basic understanding of REST web services

    — The [OpenAPI Initiative](https://www.openapis.org/) for the standardized format used in this document.

    ## Related Information
    The definition and explanation of acronyms and terminology and typographic conventions can be found in the following documents:

    — IoTA Glossary of Terms and Acronyms

    — Typographic Conventions

    # General API Guidelines

    ## Compatibility

    API audience must be prepared for compatible API extensions:

    - Be tolerant with unknown fields in the payload (see also Fowler's "TolerantReader" post), i.e. ignore new fields but do not eliminate them from payload if needed for subsequent PUT requests.
    - Be prepared that "x-extensible-enum" return parameter may deliver new values. Either be agnostic or provide default behavior for unknown values.
    - Be prepared to handle HTTP status codes not explicitly specified in endpoint definitions.
    - Follow the redirect when the server returns HTTP status 301 Moved Permanently.

    ## Security

    This section describes the security measures in the API. Security measures include authentication, authorization, and encryption.

    ### Authentication and Authorization

    The API uses OAuth2 and OpenID Connect (OIDC) for authentication and authorization.

    All API endpoints require authentication, which is performed by passing a token in the Authorization header in each request, preceded by the word Bearer and a space. See the following example:
    ```
    curl -i -X GET "https://{baseURL}/iot/api/specifications" -H "Content-Type: application/json" -H "Authorization: Bearer <TOKEN_GOES_HERE>"
    ```
    To fetch the token using e.g. curl, submit the following:
    ```
    curl -X POST "https://<baseURL>/iot/api/auth/token" -H "Accept: application/vnd.dcp-v1+json" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=password&client_id=<client_id>&username=<username>&password=<password>"
    ```
    ### Encryption

    All API requests are encrypted using the HTTPS protocol to grant secure data transfer.

    ### Permission
    API permissions are authorized by authorization server based on the account roles. Required permissions for this API are documented in 'securitySchemes' section.
    You can view available permissions for your account through permission library in Service Portal by navigating Administration > Users & roles > Permission library > <PERMISSION_NAME>
    or Role administration > Actions > View permission library.

    Make sure permissions <PERMISSION_NAME> are available to your account before you start utilizing this API.


    ## Deprecation

    API deprecation will be reflected in the OpenAPI definition. If a method on a path, a whole path or even a whole API endpoint (multiple paths) should be deprecated, they will be marked as deprecated.
    During deprecation phase, a Deprecation header and a Sunset header fields will be added in the response.

    Example:
    ```
    Deprecation: Tue, 31 Dec 2024 23:59:59 GMT
    Sunset: Wed, 31 Dec 2025 23:59:59 GMT
    ```

    API audience should not start using a deprecated API.

    API audience is encouraged to monitor for Deprecation and Sunset header.
  contact:
    name: 'Aeris IoT SaaS'
    url: 'https://support.aeris.net/hc/en-us'
  x-audience: external-partner
  x-api-id: ac36768c-7f68-44af-8035-bd7fb4994750
servers:
  - url: 'https://iot-api.aeris.com/iot/api'
    description: 'Main API server'
security:
  - Oauth2_auth: []
tags:
  - name: Specifications
    description: |
      Specification Management APIs are for user to get specifications info
  - name: File Shares
    description: |
      File Shares APIs are for user to get necessary file share info for creating or modifying a specification
paths:
  /specifications:
    get:
      tags:
        - Specifications
      summary: List all specifications
      description: |
        Retrieve summary information on the specifications from DCP. The specifications will be filtered, sorted and paged according to query parameters.
      operationId: listSpecifications
      parameters:
        - name: q
          in: query
          schema:
            type: string
          required: true
          description: |
            Filter parameter which supports the RSQL filter syntax. RSQL is a super-set of the Feed Item Query Language (FIQL).
            Currently there are only 2 fields(type, organizationId) available for search, while 'type' is mandatory in the query string and needs to be combined with the other fields. Possible values of type are:
            - SIM
            - FORM
            - PROFILE
          example: type==SIM;organizationId==3.88
        - name: cursor
          in: query
          schema:
            type: string
            default: '0'
          required: false
          description: |
            Used for accessing additional items in the list. If limit is 100 then cursor=100 will return items 101-200.
          example: '100'
        - name: limit
          in: query
          schema:
            type: integer
            format: int32
            minimum: 0
            default: 100
          required: false
          description: |
            The maximum number of results to be returned. Allowed interval is 1-1000, default value: 100. Use cursor parameter to
            set the start index.
          example: 100
        - name: sort
          in: query
          schema:
            type: string
            pattern: (\+|-)(\w+)
            default: +id
          required: false
          description: |
            Sort properties for the list of items. Use + before field name to sort ascending and - to sort descending.
          example: +status
      responses:
        "200":
          description: OK
          allOf:
            - $ref: '#/components/responses/RateLimitedResponse'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpecificationListResponse'
        "400":
          $ref: '#/components/responses/BadRequestWithInvalidParams'
        "401":
          $ref: '#/components/responses/Unauthorized'
        "403":
          $ref: '#/components/responses/Forbidden'
        "405":
          $ref: '#/components/responses/MethodNotAllowed'
        '429':
          $ref: '#/components/responses/429'
        "500":
          $ref: '#/components/responses/InternalServerError'
        default:
          description: Internal Server Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - Oauth2_auth:
            - ssm.sim-spec.read
            - ssm.euicc-spec.read
  /specifications/{id}:
    get:
      tags:
        - Specifications
      summary: Get specific specification
      description: Get one specification by ID
      operationId: getSpecificationDetails
      parameters:
        - name: id
          in: path
          schema:
            type: string
          required: true
          description: The ID of specification
          example: '75654'
      responses:
        "200":
          description: OK
          allOf:
            - $ref: '#/components/responses/RateLimitedResponse'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpecificationDetails'
        "400":
          $ref: '#/components/responses/BadRequest'
        "401":
          $ref: '#/components/responses/Unauthorized'
        "403":
          $ref: '#/components/responses/Forbidden'
        "405":
          $ref: '#/components/responses/MethodNotAllowed'
        '429':
          $ref: '#/components/responses/429'
        "500":
          $ref: '#/components/responses/InternalServerError'
        default:
          description: Internal Server Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - Oauth2_auth:
            - ssm.sim-spec.read
            - ssm.euicc-spec.read
  /file-shares:
    get:
      tags:
        - File Shares
      summary: List all file share resources
      description: List all file share resources under an organization
      operationId: listFileShares
      parameters:
        - name: organizationId
          in: query
          description: Organization ID
          schema:
            type: string
            pattern: (^\d+\.\d+[\.\d+]+)
          example: '3.88'
        - name: cursor
          in: query
          schema:
            type: string
            default: '0'
          required: false
          description: |
            Used for accessing additional items in the list. If limit is 100 then cursor=100 will return items 101-200.
          example: '100'
        - name: limit
          in: query
          schema:
            type: integer
            format: int32
            minimum: 0
            default: 100
          required: false
          description: |
            The maximum number of results to be returned. Allowed interval is 1-1000, default value: 100. Use curson parameter to
            set the start index.
          example: 10
      responses:
        "200":
          description: OK
          allOf:
            - $ref: '#/components/responses/RateLimitedResponse'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileShareListResponse'
        "400":
          $ref: '#/components/responses/BadRequestWithInvalidParams'
        "401":
          $ref: '#/components/responses/Unauthorized'
        "403":
          $ref: '#/components/responses/Forbidden'
        "405":
          $ref: '#/components/responses/MethodNotAllowed'
        '429':
          $ref: '#/components/responses/429'
        "500":
          $ref: '#/components/responses/InternalServerError'
        default:
          description: Internal Server Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - Oauth2_auth:
            - ssm.sim-spec.read
            - ssm.sim-spec.write
            - ssm.euicc-spec.read
            - ssm.euicc-spec.write
  /file-shares/{id}:
    get:
      tags:
        - File Shares
      summary: Get a file share resources
      description: Get a file share resources under an organization
      operationId: getFileShare
      parameters:
        - name: id
          in: path
          schema:
            type: string
            example: '75654'
          required: true
          description: The ID of file share
      responses:
        "200":
          description: OK
          allOf:
            - $ref: '#/components/responses/RateLimitedResponse'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileShare'
        "400":
          $ref: '#/components/responses/BadRequestWithInvalidParams'
        "401":
          $ref: '#/components/responses/Unauthorized'
        "403":
          $ref: '#/components/responses/Forbidden'
        "405":
          $ref: '#/components/responses/MethodNotAllowed'
        '429':
          $ref: '#/components/responses/429'
        "500":
          $ref: '#/components/responses/InternalServerError'
        default:
          description: Internal Server Error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - Oauth2_auth:
            - ssm.sim-spec.read
            - ssm.sim-spec.write
            - ssm.euicc-spec.read
            - ssm.euicc-spec.write
components:
  securitySchemes:
    Oauth2_auth:
      type: oauth2
      flows:
        password:
          tokenUrl: 'https://iot-api.aeris.com/iot/api/auth/token'
          scopes:
            ssm.sim-spec.read: Read access to sim spec resources in SSM
            ssm.euicc-spec.read: Read access to eUICC spec resources in SSM
            ssm.sim-spec.write: Write access to sim spec resources in SSM
            ssm.euicc-spec.write: Write access to eUICC spec resources in SSM
  responses:
    RateLimitedResponse:
      headers:
        X-RateLimit-Limit-Second:
          $ref: '#/components/headers/X-RateLimit-Limit-Second'
        X-RateLimit-Limit-Minute:
          $ref: '#/components/headers/X-RateLimit-Limit-Minute'
        X-RateLimit-Remaining-Second:
          $ref: '#/components/headers/X-RateLimit-Remaining-Second'
        X-RateLimit-Remaining-Minute:
          $ref: '#/components/headers/X-RateLimit-Remaining-Minute'
        Content-Type:
          $ref: '#/components/headers/Content-Type'
    BadRequest:
      description: Bad Request
      allOf:
        - $ref: '#/components/responses/RateLimitedResponse'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://www.iana.org/assignments/http-status-codes/
            title: "Bad Request"
            status: 400
            detail: "Query not understandable"
            instance: https://example-host/iot/api/problems/423e4563-e89b-12d3-a456-426614175000
    BadRequestWithInvalidParams:
      description: Bad Request with invalid parameters
      allOf:
        - $ref: '#/components/responses/RateLimitedResponse'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/InvalidParamsProblem'
          example:
            type: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1
            title: Bad Request
            status: 400
            detail: Invalid request
            instance: UNSET  # May be a URI or the literal string 'UNSET' depending on context
            parameters:
              invalid-params:
                - name: q
                  violation: "q must be in format: type==SIM;organizationId==3.88.7"
    InternalServerError:
      description: Internal Server Error
      allOf:
        - $ref: '#/components/responses/RateLimitedResponse'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://www.iana.org/assignments/http-status-codes/
            title: "Internal Server Error"
            status: 500
            detail: "Internal Server Error occurred while processing the request."
            instance: https://example-host/iot/api/problems/523e4562-e89b-12d3-a456-426614175000
    Unauthorized:
      description: Unauthorized
      allOf:
        - $ref: '#/components/responses/RateLimitedResponse'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://www.iana.org/assignments/http-status-codes/
            title: "Unauthorized"
            status: 401
            detail: No or invalid authentication token provided
            instance: https://example-host/iot/api/problems/523e1562-e89b-12d3-a456-426614175000
    Forbidden:
      description: Forbidden
      allOf:
        - $ref: '#/components/responses/RateLimitedResponse'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://www.iana.org/assignments/http-status-codes/
            title: "Forbidden"
            status: 403
            detail: Permission missing
            instance: https://example-host/iot/api/problems/523e2562-e89b-12d3-a456-426614175000
    MethodNotAllowed:
      description: Method Not Allowed
      allOf:
        - $ref: '#/components/responses/RateLimitedResponse'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://www.iana.org/assignments/http-status-codes/
            title: "Method Not Allowed"
            status: 405
            detail: POST is not allowed in this endpoint
            instance: https://example-host/iot/api/problems/523e9562-e89b-12d3-a456-426614175000
    '429':
      description: Too Many Requests
      allOf:
        - $ref: '#/components/responses/RateLimitedResponse'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: about:blank
            title: Too Many Requests
            status: 429
            detail: Too Many Requests. Please refer response RateLimit-* headers before send requests.
            instance: about:blank
    Problem:
      description: |
        error occurred - see status code and problem object for more
        information.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  schemas:
    SpecificationListResponse:
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Specification'
        next:
          type: string
          nullable: true
          description: URI to next pagination.
          example: "/specifications?cursor=VSDFDB3434%DFB%EYY336"
    Specification:
      type: object
      properties:
        id:
          type: string
          example: '75654'
        specificationId:
          type: string
          example: 'PS OpTest1'
        type:
          type: string
          x-extensible-enum:
            - SIM
            - FORM
            - PROFILE
          example: SIM
        status:
          type: string
          nullable: true
          x-extensible-enum:
            - ACTIVE
            - DEPRECATED
          example: ACTIVE
        name:
          type: string
          minLength: 1
          maxLength: 255
          example: 'SIM Specification For Test'
        description:
          type: string
          nullable: true
          minLength: 1
          maxLength: 240
          example: Plastic SIM
        maxQuantity:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        minQuantity:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        minOrderVolume:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        orderIncrement:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        priceCategory:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        numberSchemeId:
          type: string
          nullable: true
          example: 'ZZRSCHEME00021'
        createdAt:
          type: string
          format: date-time
        fivegSaEnabled:
          description: Indicates if the SIM supports 5G Standalone. Present only if 5G SA is enabled.
          type: boolean
          nullable: true
          x-omit-if-null: true
          example: true
    SpecificationDetails:
      type: object
      properties:
        id:
          type: string
          example: '75654'
        specificationId:
          type: string
          example: 'PS OpTest1'
        type:
          type: string
          nullable: true
          x-extensible-enum:
            - SIM
            - FORM
            - PROFILE
          example: SIM
        status:
          type: string
          nullable: true
          x-extensible-enum:
            - ACTIVE
            - DEPRECATED
          example: ACTIVE
        name:
          type: string
          minLength: 1
          maxLength: 255
          example: 'SIM Specification For Test'
        description:
          type: string
          nullable: true
          minLength: 1
          maxLength: 240
          example: Plastic SIM
        maxQuantity:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        minQuantity:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        minOrderVolume:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        orderIncrement:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        earliestDeliveryDays:
          type: integer
          nullable: true
          format: int32
          minimum: 0
          description: how many days the order needs to be delivered
        priceCategory:
          type: integer
          nullable: true
          format: int32
          minimum: 0
        stockOrderFileShareId:
          type: string
          nullable: true
          example: '75654'
        manufacturerOrderFileShareId:
          type: string
          nullable: true
          example: '75654'
        warehouseOrderFileShareId:
          type: string
          nullable: true
          example: '75654'
        profileStockOrderFileShareId:
          type: string
          nullable: true
          example: '75654'
        numberSchemeId:
          type: string
          nullable: true
          example: 'ZZRSCHEME00021'
        earlyBinding:
          type: boolean
        smsrId:
          type: string
          nullable: true
          minLength: 1
          maxLength: 100
          description: Subscription Manager Secure Routing
          example: 1.2.3.4
        smdpId:
          type: string
          nullable: true
          minLength: 1
          maxLength: 100
          description: Subscription Manager Data Preparation
          example: 5.6.7.8
        bootstrapProfileType:
          type: string
          nullable: true
          x-extensible-enum:
            - BOOTSTRAP
            - VIRTUAL
            - PROVISIONING
            - OPERATIONAL
          example: VIRTUAL
        formSpecificationType:
          type: string
          nullable: true
          x-extensible-enum:
            - M2M
            - CONSUMER
          example: M2M
        operatorNetworkId:
          type: string
          nullable: true
          example: '75654'
        operatorId:
          type: string
          nullable: true
          example: '75654'
        formSpecificationIds:
          description: Form specifications that linked to this spec
          type: array
          nullable: true
          items:
            type: string
          example: ['663679', '665200', '564305']
        profileSpecificationIds:
          description: Profile specifications that linked to this spec
          type: array
          nullable: true
          items:
            type: string
          example: ['564393']
        createdAt:
          type: string
          format: date-time
        createdBy:
          type: string
          minLength: 1
          maxLength: 100
          example: admin@aeris.net
        updatedAt:
          type: string
          format: date-time
        fivegSaEnabled:
          description: Indicates if the SIM supports 5G Standalone. Present only if 5G SA is enabled.
          type: boolean
          nullable: true
          x-omit-if-null: true
          example: true
    FileShareListResponse:
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/FileShare'
        next:
          type: string
          nullable: true
          description: URI to next pagination.
          example: "/file-shares?cursor=VSDFDB3434%DFB%EYY336"
    FileShare:
      type: object
      properties:
        id:
          type: string
          example: '755654'
        name:
          type: string
          minLength: 1
          maxLength: 255
          example: DEFAULT
        status:
          type: string
          x-extensible-enum:
            - DRAFT
            - SUBMITTED
            - ACTIVE
            - INVALID
            - OBSOLETE
          example: ACTIVE
        fileShareType:
          type: string
          x-extensible-enum:
            - STOCK_ORDER
            - WAREHOUSE_ORDER
            - MANUFACTURER_ORDER
            - PROFILE_STOCK_ORDER
          example: WAREHOUSE_ORDER
        fileShareURI:
          type: string
          minLength: 1
          maxLength: 1024
          example: /share/FILESHAREWAREHOUSEORDEREUICC
        description:
          type: string
          minLength: 1
          maxLength: 500
          example: Profile Spec for OpTest1
    Problem:
      type: object
      properties:
        type:
          type: string
          format: uri
          description: |
            An absolute URI that identifies the problem type. When
            dereferenced, it SHOULD provide human-readable documentation
            for the problem type (e.g., using HTML).
          default: 'about:blank'
          example: 'https://your.api.documentation.url'
        title:
          type: string
          description: |
            A short, summary of the problem type. Written in english and
            readable for engineers (usually not suited for non technical
            stakeholders and not localized).
          example: Service Unavailable
        status:
          type: integer
          format: int32
          description: |
            The HTTP status code generated by the origin server for this
            occurrence of the problem.
          minimum: 100
          maximum: 600
          example: 400
        detail:
          type: string
          description: |
            A human readable explanation specific to this occurrence of the
            problem.
          example: Connection to database timed out
        instance:
          type: string
          description: |
            An absolute URI that identifies the specific occurrence of the
            problem. It may or may not yield further information if
            dereferenced. May be a URI or the literal string 'UNSET' depending on context
        parameters:
          type: object
          additionalProperties: true
          description: |
            Additional properties related to the problem.
    InvalidParamsProblem:
      description: A Problem object extended with an invalid-params array describing parameter validation failures.
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          properties:
            parameters:
              type: object
              properties:
                invalid-params:
                  type: array
                  description: List of invalid parameters causing the request to fail.
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        description: Name of the offending parameter.
                        example: q
                      violation:
                        type: string
                        description: Description of the validation error.
                        example: "q must be in format: type==SIM;organizationId==3.88.7"
                    required:
                      - name
                      - violation
              additionalProperties: true
  headers:
    Content-Type:
      description: Handle Content-Type
      schema:
        type: string
    X-RateLimit-Limit-Second:
      description: The maximum number of requests allowed in a second.
      schema:
        type: integer
        format: int32
    X-RateLimit-Limit-Minute:
      description: The maximum number of requests allowed in a minute.
      schema:
        type: integer
        format: int32
    X-RateLimit-Remaining-Second:
      description: The number of requests remaining in a second.
      schema:
        type: integer
        format: int32
    X-RateLimit-Remaining-Minute:
      description: The number of requests remaining in a minute.
      schema:
        type: integer
        format: int32
