swagger: '2.0'
info:
  version: 1.1.0
  title: IO API for administration purpose
  contact:
    name: Digital Transformation Team
    url: https://forum.italia.it/c/progetto-io
  x-logo:
    url: https://io.italia.it/assets/img/io-logo-blue.svg
  description: >
    # Warning

    **This is an experimental API that is (most probably) going to change as we
    evolve the IO platform.**

    # Introduction

    This is the documentation of the IO API for administration purpose of the
    platform.
host: api.cd.italia.it
basePath: /adm
schemes:
  - https
security:
  - SubscriptionKey: []
paths:
  /services/{service_id}:
    parameters:
      - name: service_id
        in: path
        type: string
        required: true
        description: The ID of an existing Service.
    get:
      operationId: getService
      summary: Get Service
      description: A previously created service with the provided service ID is returned.
      responses:
        '200':
          description: Service found.
          schema:
            $ref: '#/definitions/Service'
          examples:
            application/json:
              id: 2b3e728c1a5d1efa035c-0000000000000001
              authorized_recipients:
                - XXXYYY79A95Y000X
              department_name: dept
              organization_name: org
              service_id: 2b3e728c1a5d1efa035c
              service_name: service
              version: 1
              authorized_cidrs: []
        '401':
          description: Unauthorized
        '404':
          description: No service found for the provided ID.
      parameters: []
    put:
      responses:
        '200':
          description: Service updated.
          schema:
            $ref: '#/definitions/Service'
          examples:
            application/json:
              id: 2b3e728c1a5d1efa035c-0000000000000001
              authorized_recipients:
                - XXXYYY79A95Y000X
              department_name: dept
              organization_name: org
              service_id: 2b3e728c1a5d1efa035c
              service_name: service
              version: 1
              authorized_cidrs: []
        '401':
          description: Unauthorized
        '404':
          description: No service found for the provided ID.
      summary: Update Service
      operationId: updateService
      description: |-
        Update an existing service with the attributes provided in the
        request payload.
      parameters:
        - in: body
          name: body
          schema:
            $ref: '#/definitions/Service'
          description: The Service payload.
          x-examples:
            application/json:
              authorized_recipients:
                - XXXYYY79A95Y000X
              department_name: dept
              organization_name: org
              service_id: 2b3e728c1a5d1efa035c
              service_name: service
              authorized_cidrs: []
  /services/{service_id}/logo:
    parameters:
      - name: service_id
        in: path
        type: string
        required: true
        description: The ID of a existing Service.
    put:
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/Logo'
          description: The logo payload
      responses:
        '201':
          description: Logo uploaded.
          headers:
            Location:
              description: Link to the uploaded logo
              type: string
        '400':
          description: Invalid payload.
          schema:
            $ref: '#/definitions/ProblemJson'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: No service found for the provided ID.
        '500':
          description: Internal server error
      summary: Upload service logo.
      operationId: uploadServiceLogo
  /services:
    get:
      summary: Get Services
      operationId: getServices
      description: Gets the list of all existing services.
      responses:
        '200':
          description: The list of server.
          schema:
            $ref: '#/definitions/ServiceCollection'
        '500':
          description: Internal server error.
    post:
      responses:
        '200':
          description: Service created.
          schema:
            $ref: '#/definitions/Service'
          examples:
            application/json:
              id: 2b3e728c1a5d1efa035c-0000000000000001
              authorized_recipients:
                - XXXYYY79A95Y000X
              department_name: dept
              organization_name: org
              service_id: 2b3e728c1a5d1efa035c
              service_name: service
              version: 1
              authorized_cidrs: []
        '401':
          description: Unauthorized
      summary: Create Service
      description: |-
        Create a new Service with the attributes provided in the requst
        payload.
      operationId: createService
      parameters:
        - in: body
          name: body
          schema:
            $ref: '#/definitions/Service'
          description: The Service payload.
          x-examples:
            application/json:
              authorized_recipients:
                - XXXYYY79A95Y000X
              department_name: dept
              organization_name: org
              service_id: 2b3e728c1a5d1efa035c
              service_name: service
              authorized_cidrs: []
  /organizations/{organization_fiscal_code}/logo:
    parameters:
      - name: organization_fiscal_code
        in: path
        type: string
        required: true
        description: The organization's fiscal code
    put:
      summary: Upload Organization Logo
      description: Upload an organization logo for the given organization fiscal code.
      operationId: uploadOrganizationLogo
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/Logo'
          description: The logo payload
      responses:
        '201':
          description: Logo uploaded.
          headers:
            Location:
              description: Link to the uploaded logo
              type: string
        '400':
          description: Invalid payload.
          schema:
            $ref: '#/definitions/ProblemJson'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
  /development-profiles/{fiscal_code}:
    post:
      tags:
        - restricted
      description: |-
        Create a development profile for the user identified by the
        provided fiscal code.
      operationId: createDevelopmentProfile
      summary: Create DevelopmentProfile
      parameters:
        - $ref: '#/parameters/SandboxFiscalCode'
        - in: body
          name: body
          schema:
            $ref: '#/definitions/DevelopmentProfile'
          x-examples:
            application/json:
              email: foobar@example.com
      responses:
        '200':
          description: Profile updated.
          schema:
            $ref: '#/definitions/ExtendedProfile'
          examples:
            application/json:
              email: foobar@example.com
              version: 0
        '400':
          description: Invalid payload.
          schema:
            $ref: '#/definitions/ProblemJson'
        '401':
          description: Unauthorized
        '409':
          description: Conflict.
          schema:
            $ref: '#/definitions/ProblemJson'
        '429':
          description: Too many requests
  /services/{service_id}/keys:
    get:
      summary: >-
        Gets the subscription keys for the Service identified by the provided
        service_id
      operationId: getSubscriptionKeys
      parameters:
        - name: service_id
          in: path
          type: string
          required: true
          description: The ID of an existing Service.
      responses:
        '200':
          description: The subscription keys for the service
          schema:
            $ref: '#/definitions/SubscriptionKeys'
        '400':
          description: Bad request
        '403':
          description: Forbidden
        '404':
          description: Subscription not found
        '500':
          description: Internal server error
    put:
      summary: >-
        Regenerate a subscription key for the Service identified by the provided
        service_id
      operationId: RegenerateSubscriptionKeys
      parameters:
        - name: service_id
          in: path
          type: string
          required: true
          description: The ID of an existing Service.
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/SubscriptionKeyTypePayload'
          description: The type of the key to be regenerated
      responses:
        '200':
          description: The subscription keys for the service
          schema:
            $ref: '#/definitions/SubscriptionKeys'
        '400':
          description: Bad request
        '403':
          description: Forbidden
        '404':
          description: Subscription not found
        '500':
          description: Internal server error
  /users:
    get:
      summary: Gets the list of users
      operationId: getUsers
      parameters:
        - name: cursor
          description: the number of items to skip.
          in: query
          type: integer
          minimum: 1
      responses:
        '200':
          description: List of users
          schema:
            $ref: '#/definitions/UserCollection'
    post:
      summary: Create user
      description: >-
        Create a new user with a random password in the Active Directory Azure
        B2C, then create a corresponding user on the API management resource.
      operationId: createUser
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/UserPayload'
      responses:
        '200':
          description: The new User
          schema:
            $ref: '#/definitions/UserCreated'
        '400':
          description: Bad request
        '403':
          description: Forbidden
        '500':
          description: Internal server error
  /users/{email}:
    get:
      summary: Get user
      description: >-
        Gets the user information, that is the complete list of subscription and
        the complete list of groups for the User identified by the provided
        email
      operationId: getUser
      parameters:
        - name: email
          in: path
          type: string
          format: email
          required: true
          description: The email of the User
      responses:
        '200':
          description: User subscriptions and groups
          schema:
            $ref: '#/definitions/UserInfo'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: User not found
        '500':
          description: Internal server error
    put:
      summary: Update user
      description: Update an existing ADB2C User.
      operationId: updateUser
      parameters:
        - name: email
          in: path
          type: string
          format: email
          required: true
          description: The email of the User
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/UserUpdatePayload'
      responses:
        '200':
          description: The updated User
          schema:
            $ref: '#/definitions/UserUpdated'
        '400':
          description: Bad request
        '403':
          description: Forbidden
        '500':
          description: Internal server error
  /users/{email}/groups:
    put:
      summary: Update user groups
      description: >-
        Update the list of groups (permissions) associated to the User
        identified by the provided email
      operationId: updateGroups
      parameters:
        - name: email
          in: path
          type: string
          format: email
          required: true
          description: The email of the User
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/UserGroupsPayload'
      responses:
        '200':
          description: The list of groups associated to the User
          schema:
            $ref: '#/definitions/GroupCollection'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Resource (User or Product) not found
        '500':
          description: Internal server error
  /users/{email}/subscriptions/{subscription_id}:
    put:
      summary: Create subscription
      description: >-
        Create a Subscription identified by the provided subscription id for the
        User identified by the provided email
      operationId: createSubscription
      parameters:
        - name: email
          in: path
          type: string
          format: email
          required: true
          description: The email of the User
        - name: subscription_id
          in: path
          type: string
          required: true
          description: The id of the Subscription
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/ProductNamePayload'
      responses:
        '200':
          description: The subscription created
          schema:
            $ref: '#/definitions/Subscription'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Resource (User or Product) not found
        '500':
          description: Internal server error
definitions:
  DevelopmentProfile:
    type: object
    properties:
      email:
        $ref: '#/definitions/EmailAddress'
    required:
      - email
  EmailAddress:
    type: string
    format: email
    example: foobar@example.com
  ServiceCollection:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: '#/definitions/ServiceIdWithVersion'
      page_size:
        type: number
    required:
      - items
      - page_size
  ProblemJson:
    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://example.com/problem/constraint-violation
      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
        exclusiveMaximum: true
        example: 200
      detail:
        type: string
        description: |-
          A human readable explanation specific to this occurrence of the
          problem.
        example: There was an error processing the request
      instance:
        type: string
        format: uri
        description: >-
          An absolute URI that identifies the specific occurrence of the
          problem.

          It may or may not yield further information if dereferenced.
  Service:
    description: A service tied to user's subscription.
    allOf:
      - $ref: '#/definitions/ServicePayload'
      - type: object
        properties:
          id:
            type: string
          service_id:
            $ref: '#/definitions/ServiceId'
          authorized_recipients:
            description: |-
              If non empty, the service will be able
              to send messages only to these fiscal codes.
            type: array
            items:
              $ref: '#/definitions/FiscalCode'
          max_allowed_payment_amount:
            $ref: '#/definitions/MaxAllowedPaymentAmount'
        required:
          - service_id
          - authorized_recipients
  ServiceMetadata:
    type: object
    description: A set of metadata properties related to this service.
    properties:
      description:
        type: string
        minLength: 1
      web_url:
        type: string
        minLength: 1
      app_ios:
        type: string
        minLength: 1
      app_android:
        type: string
        minLength: 1
      tos_url:
        type: string
        minLength: 1
      privacy_url:
        type: string
        minLength: 1
      address:
        type: string
        minLength: 1
      phone:
        type: string
        minLength: 1
      email:
        type: string
        minLength: 1
      pec:
        type: string
        minLength: 1
      cta:
        type: string
        minLength: 1
      token_name:
        type: string
        minLength: 1
      support_url:
        type: string
        minLength: 1
      scope:
        $ref: '#/definitions/ServiceScope'
    required:
      - scope
  ServiceScope:
    type: string
    x-extensible-enum:
      - NATIONAL
      - LOCAL
  ServicePayload:
    description: A payload used to create/update a service for a user.
    x-one-of: true
    allOf:
      - $ref: '#/definitions/VisibleServicePayload'
      - $ref: '#/definitions/HiddenServicePayload'
  HiddenServicePayload:
    description: A payload used to create/update a service that is hidden.
    allOf:
      - $ref: '#/definitions/CommonServicePayload'
      - type: object
        properties:
          is_visible:
            type: boolean
            default: false
            enum:
              - false
            description: It indicates that service is hidden
          service_metadata:
            $ref: '#/definitions/ServiceMetadata'
  VisibleServicePayload:
    description: >-
      A payload used to create/update a service that appears in the service
      list.
    allOf:
      - $ref: '#/definitions/CommonServicePayload'
      - type: object
        properties:
          is_visible:
            type: boolean
            enum:
              - true
            description: It indicates that service appears in the service list
          service_metadata:
            $ref: '#/definitions/ServiceMetadata'
        required:
          - is_visible
          - service_metadata
  CommonServicePayload:
    description: Common properties for a ServicePayload
    type: object
    properties:
      service_name:
        $ref: '#/definitions/ServiceName'
      department_name:
        $ref: '#/definitions/DepartmentName'
      organization_name:
        $ref: '#/definitions/OrganizationName'
      organization_fiscal_code:
        $ref: '#/definitions/OrganizationFiscalCode'
      authorized_cidrs:
        description: >-
          Allowed source IPs or CIDRs for this service.

          When empty, every IP address it's authorized to call the IO API on
          behalf of the service.
        type: array
        items:
          $ref: '#/definitions/CIDR'
      version:
        type: integer
      require_secure_channels:
        type: boolean
        default: false
        description: When true, messages won't trigger email notifications (only push).
    required:
      - service_name
      - department_name
      - organization_name
      - organization_fiscal_code
      - authorized_cidrs
  ServiceId:
    type: string
    description: |-
      The ID of the Service. Equals the subscriptionId of a registered
      API user.
    minLength: 1
  ServiceName:
    type: string
    description: The name of the service. Will be added to the content of sent messages.
    minLength: 1
  OrganizationName:
    type: string
    description: |-
      The organization that runs the service. Will be added to the content
      of sent messages to identify the sender.
    minLength: 1
  DepartmentName:
    type: string
    description: |-
      The department inside the organization that runs the service. Will
      be added to the content of sent messages.
    minLength: 1
  CIDR:
    type: string
    description: Describes a single IP or a range of IPs.
    pattern: ^([0-9]{1,3}[.]){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$
  MaxAllowedPaymentAmount:
    description: >-
      Maximum amount in euro cents that a service is allowed to charge to a
      user.
    type: integer
    minimum: 0
    maximum: 9999999999
    default: 0
  OrganizationFiscalCode:
    type: string
    description: Organization fiscal code.
    format: OrganizationFiscalCode
    x-import: italia-ts-commons/lib/strings
    example: '12345678901'
  FiscalCode:
    type: string
    description: User's fiscal code.
    format: FiscalCode
    x-import: italia-ts-commons/lib/strings
    example: SPNDNL80R13C555X
  ExtendedProfile:
    description: |-
      Describes the citizen's profile, mostly interesting for preferences
      attributes.
    type: object
    properties:
      email:
        $ref: '#/definitions/EmailAddress'
      blocked_inbox_or_channels:
        type: object
        additionalProperties:
          type: array
          items:
            type: string
            description: |-
              All notification channels plus the message inbox.
              These represent all the possible channels a user could block.
            x-extensible-enum:
              - EMAIL
              - INBOX
              - WEBHOOK
            example: INBOX
        description: |-
          All the notification channels blocked by the user.
          Each channel is related to a specific service (sender).
      preferred_languages:
        type: array
        items:
          type: string
          x-extensible-enum:
            - it_IT
            - en_GB
            - es_ES
            - de_DE
            - fr_FR
          example: it_IT
        description: >-
          Indicates the User's preferred written or spoken languages in order

          of preference. Generally used for selecting a localized User
          interface. Valid

          values are concatenation of the ISO 639-1 two letter language code, an
          underscore,

          and the ISO 3166-1 2 letter country code; e.g., 'en_US' specifies the
          language

          English and country US.
      is_inbox_enabled:
        type: boolean
        description: |-
          True if the recipient of a message wants to store its content for
          later retrieval.
      accepted_tos_version:
        type: number
        minimum: 1
        description: Version of latest terms of service accepted by the user.
      is_webhook_enabled:
        type: boolean
        description: >-
          True if the recipient of a message wants to forward the notifications
          to the default webhook.
      is_email_enabled:
        type: boolean
        description: >-
          True if the recipient of a message wants to forward the notifications
          to his email address.
      is_email_validated:
        type: boolean
        description: True if the user email has been validated.
      is_test_profile:
        type: boolean
        description: True if the user's profile is only for test purpose.
        default: false
      version:
        type: integer
    required:
      - is_email_enabled
      - is_email_validated
      - is_inbox_enabled
      - is_webhook_enabled
      - version
  UserGroupsPayload:
    description: >-
      All the groups with which the user must be associated.

      The already existing associations with groups which are not included in
      this object will be deleted.
    type: object
    properties:
      groups:
        type: array
        items:
          description: The value of `displayName` property of the group on the APIM
          type: string
          minLength: 1
    required:
      - groups
    example:
      groups:
        - ApiInfoRead
        - ApiLimitedMessageWrite
        - ApiMessageRead
  UserPayload:
    type: object
    properties:
      email:
        $ref: '#/definitions/EmailAddress'
      first_name:
        type: string
        minLength: 1
      last_name:
        type: string
        minLength: 1
      token_name:
        type: string
        minLength: 1
    required:
      - email
      - first_name
      - last_name
  UserUpdatePayload:
    type: object
    properties:
      first_name:
        type: string
        minLength: 1
      last_name:
        type: string
        minLength: 1
      token_name:
        type: string
        minLength: 1
  UserCreated:
    allOf:
      - $ref: '#/definitions/UserPayload'
      - type: object
        properties:
          id:
            type: string
        required:
          - id
  UserUpdated:
    allOf:
      - $ref: '#/definitions/UserUpdatePayload'
      - type: object
        properties:
          email:
            $ref: '#/definitions/EmailAddress'
          id:
            type: string
        required:
          - id
          - email
  GroupCollection:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: '#/definitions/Group'
    required:
      - items
  Logo:
    type: object
    properties:
      logo:
        type: string
        format: byte
        minLength: 1
    required:
      - logo
  ProductNamePayload:
    type: object
    properties:
      product_name:
        type: string
        minLength: 1
    required:
      - product_name
  SubscriptionKeyTypePayload:
    type: object
    properties:
      key_type:
        $ref: '#/definitions/SubscriptionKeyType'
    required:
      - key_type
  SubscriptionKeyType:
    type: string
    x-extensible-enum:
      - PRIMARY_KEY
      - SECONDARY_KEY
  SubscriptionKeys:
    type: object
    properties:
      primary_key:
        type: string
      secondary_key:
        type: string
    required:
      - primary_key
      - secondary_key
  User:
    type: object
    properties:
      email:
        $ref: '#/definitions/EmailAddress'
      id:
        type: string
      identities:
        type: array
        items:
          $ref: '#/definitions/UserIdentityContract'
      first_name:
        type: string
      last_name:
        type: string
      name:
        type: string
      note:
        type: string
      registration_date:
        type: string
        format: date-time
      state:
        $ref: '#/definitions/UserState'
      type:
        type: string
  UserCollection:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: '#/definitions/User'
      next:
        description: The link to the next page of results
        type: string
        format: url
    required:
      - items
  Group:
    type: object
    properties:
      display_name:
        type: string
      id:
        type: string
      name:
        type: string
    required:
      - display_name
  Subscription:
    allOf:
      - $ref: '#/definitions/SubscriptionKeys'
      - type: object
        properties:
          id:
            type: string
          scope:
            type: string
        required:
          - scope
  SubscriptionState:
    type: string
    x-extensible-enum:
      - active
      - cancelled
      - expired
      - rejected
      - submitted
      - suspended
  UserInfo:
    type: object
    properties:
      groups:
        type: array
        items:
          $ref: '#/definitions/Group'
      subscriptions:
        type: array
        items:
          $ref: '#/definitions/Subscription'
      token_name:
        type: string
        minLength: 1
  UserIdentityContract:
    type: object
    properties:
      id:
        type: string
      provider:
        type: string
  UserState:
    type: string
    x-extensible-enum:
      - active
      - blocked
      - pending
      - deleted
  ServiceIdWithVersion:
    type: object
    properties:
      id:
        type: string
      version:
        type: integer
  ServerInfo:
    type: object
    title: Server information
    properties:
      version:
        type: string
    required:
      - version
responses: {}
parameters:
  SandboxFiscalCode:
    name: fiscal_code
    in: path
    type: string
    maxLength: 16
    minLength: 16
    required: true
    description: The user's sandbox fiscal code, all upper case.
    pattern: '[A-Z]{6}[0-9]{2}A[0-9]{2}Y[0-9]{3}X'
    x-example: SPNDNL80A13Y555X
consumes:
  - application/json
produces:
  - application/json
securityDefinitions:
  SubscriptionKey:
    type: apiKey
    name: Ocp-Apim-Subscription-Key
    in: header
    description: The API key obtained through the developer portal.
