openapi: 3.0.0
info:
  title: WSO2 Identity Server - Branding Preferences API Definition
  description: >-
    This document specifies a **RESTful API** for **Managing Branding Preferences of Organizations** in **WSO2 Identity Server**.
  contact:
    name: WSO2 Identity Server
    url: 'https://wso2.com/identity-and-access-management/'
    email: architecture@wso2.com
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  version: v1

servers:
  - url: 'https://{server-url}/t/{tenant-domain}/api/server/v1'
    variables:
      server-url:
        default: "localhost:9443"
      tenant-domain:
        default: "carbon.super"

security:
  - OAuth2: []
  - BasicAuth: []

paths:
  '/branding-preference':
    get:
      tags:
        - Branding Preference
      operationId: getBrandingPreference
      summary: Get branding preference of a tenant.
      description: |
        This API provides the capability to retrieve the branding preference of a tenant/specific application.<br>
        If there is no branding preference available for the requested locale, API will check for the default locale('en-US') and return it.<br>
        If there is no branding preference available for the requested application, API will check for the tenant's branding preference and return it.<br>
          <b>Permission required:</b> <br>
            * None <br>
          <b>Scope required:</b> <br>
            * None
      parameters:
        - $ref: '#/components/parameters/typeQueryParam'
        - $ref: '#/components/parameters/nameQueryParam'
        - $ref: '#/components/parameters/localeQueryParam'
      responses:
        '200':
          description: OK
          content:
            'application/json':
              schema:
                $ref: '#/components/schemas/BrandingPreferenceModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'

    post:
      tags:
        - Branding Preference
      operationId: addBrandingPreference
      summary: Add branding preferences for a tenant.
      description: |
        This API provides the capability to add a custom branding preference for a tenant/application.<br>
        Currently this API provides the capability to only configure tenant wise branding preference for 'en-US' locale.<br>
          <b>Permission required:</b> <br>
            * /permission/admin/manage/identity/applicationmgt/update <br>
          <b>Scope required:</b> <br>
            * internal_application_mgt_update
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BrandingPreferenceModel'
        description: This represents the branding preferences to be added.
        required: true
      responses:
        '201':
          description: Successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BrandingPreferenceModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        "409":
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/ServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'
    put:
      tags:
        - Branding Preference
      operationId: updateBrandingPreference
      summary: Update branding preferences of a tenant.
      description: |
        This API provides the capability to update the branding preference of a tenant/application.<br>
          <b>Permission required:</b> <br>
            * /permission/admin/manage/identity/applicationmgt/update <br>
          <b>Scope required:</b> <br>
            * internal_application_mgt_update
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BrandingPreferenceModel'
        description: This represents the branding preferences to be updated.
        required: true
      responses:
        '200' :
          description: Successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BrandingPreferenceModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'

    delete:
      tags:
        - Branding Preference
      operationId: deleteBrandingPreference
      summary: Deletes branding preferences of a tenant.
      description: |
        This API provides the capability to delete the branding preferences of a tenant/application.<br>
          <b>Permission required:</b> <br>
            * /permission/admin/manage/identity/applicationmgt/update <br>
          <b>Scope required:</b> <br>
            * internal_application_mgt_update
      parameters:
        - $ref: '#/components/parameters/typeQueryParam'
        - $ref: '#/components/parameters/nameQueryParam'
        - $ref: '#/components/parameters/localeQueryParam'
      responses:
        '204' :
          description: Successfully deleted.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
  '/branding-preference/resolve':
    get:
      tags:
        - Branding Preference
      operationId: resolveBrandingPreference
      summary: Resolve branding preference of an organization.
      description: |
        This API provides the capability to retrieve the branding preference of an organization/specific application.<br>
        If there is no branding preference available for the requested locale, API will check for the default locale('en-US') and return it.<br>
        If there is no branding preference available for the requested application, API will check for the organization's branding preference and return it.<br>
          <b>Permission required:</b> <br>
            * None <br>
          <b>Scope required:</b> <br>
            * None
      parameters:
        - $ref: '#/components/parameters/typeQueryParam'
        - $ref: '#/components/parameters/nameQueryParam'
        - $ref: '#/components/parameters/localeQueryParam'
        - $ref: '#/components/parameters/restrictToPublishedQueryParam'
      responses:
        '200':
          description: OK
          content:
            'application/json':
              schema:
                $ref: '#/components/schemas/ResolvedBrandingPreferenceModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
  '/branding-preference/generate':
    post:
      tags:
        - Branding Preference
      operationId: generateBrandingPreference
      summary: Generate branding preferences using AI based on the organization's website.
      description: |
        This API endpoint initiates the generation of a new set of branding preferences by leveraging AI to analyze the organization's website. This is typically used when an organization wants to create branding preferences using AI. The endpoint requires a website URL and generates matching branding details based on the website's properties.<br>
        <b>Scope(Permission) required:</b> `internal_branding_preference_update`
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BrandingGenerationRequestModel'
        description: This represents the properties of the organization used to generate branding preferences, including the organization's website URL.
        required: true
      responses:
        '202':
          description: Branding generation process started
          content:
            'application/json':
              schema:
                $ref: '#/components/schemas/BrandingGenerationResponseModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/ServerError'
  '/branding-preference/status/{operationId}':
    get:
      tags:
        - Branding Preference
      operationId: getBrandingGenerationStatus
      summary: Get the status of a branding generation operation.
      description: |
        This API endpoint returns the status of the AI branding generation process that initiated using the `/generate` endpoint.<br/>
      parameters:
        - $ref: '#/components/parameters/operationId'
      responses:
        '200':
          description: OK
          content:
            'application/json':
              schema:
                $ref: '#/components/schemas/BrandingGenerationStatusModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
  '/branding-preference/result/{operationId}':
    get:
      tags:
        - Branding Preference
      operationId: getBrandingGenerationResult
      summary: Return the result of a branding generation operation.
      description: |
        This API endpoint returns the result of an AI branding generation operation for a given operation ID. Depending on the operation status, the response may include an error message or the generated branding preferences.<br/>
      parameters:
        - $ref: '#/components/parameters/operationId'
      responses:
        '200':
          description: OK
          content:
            'application/json':
              schema:
                $ref: '#/components/schemas/BrandingGenerationResultModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'

  '/branding-preference/text':
    get:
      tags:
        - Custom Text
      operationId: getCustomText
      summary: Get Custom text of a tenant.
      description: |
        This API provides the capability to retrieve the existing custom text configurations of a tenant for the specified screen and locale.<br>
        If there is no custom texts available for the requested locale, API will check for the default locale('en-US') and return it.<br>
          <b>Permission required:</b> <br>
            * None <br>
          <b>Scope required:</b> <br>
            * None
      parameters:
        - $ref: '#/components/parameters/typeQueryParam'
        - $ref: '#/components/parameters/nameQueryParam'
        - $ref: '#/components/parameters/localeQueryParam'
        - $ref: '#/components/parameters/screenQueryParam'
      responses:
        '200':
          description: OK
          content:
            'application/json':
              schema:
                $ref: '#/components/schemas/CustomTextModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'

    post:
      tags:
        - Custom Text
      operationId: addCustomText
      summary: Add custom text for a tenant.
      description: |
        This API provides the capability to add custom texts for the specified screen & locale.<br>
          <b>Permission required:</b> <br>
            * /permission/admin/manage/identity/applicationmgt/update <br>
          <b>Scope required:</b> <br>
            * internal_application_mgt_update
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomTextModel'
        description: This represents the custom text to be added.
        required: true
      responses:
        '201':
          description: Successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomTextModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        "409":
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/ServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

    put:
      tags:
        - Custom Text
      operationId: updateCustomText
      summary: Update custom text of a tenant.
      description: |
        This API provides the capability to update the custom texts for the specified screen & locale.<br>
          <b>Permission required:</b> <br>
            * /permission/admin/manage/identity/applicationmgt/update <br>
          <b>Scope required:</b> <br>
            * internal_application_mgt_update
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomTextModel'
        description: This represents the custom text content to be updated for the specified screen & locale.
        required: true
      responses:
        '200' :
          description: Successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomTextModel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'

    delete:
      tags:
        - Custom Text
      operationId: deleteCustomText
      summary: Deletes custom text.
      description: |
        This API provides the capability to delete the custom texts for the specified screen & locale of a tenant.<br>
        If no query parameter was specified in the delete request, all the custom texts configured in the tenant will be deleted.<br>
          <b>Permission required:</b> <br>
            * /permission/admin/manage/identity/applicationmgt/update <br>
          <b>Scope required:</b> <br>
            * internal_application_mgt_update
      parameters:
        - $ref: '#/components/parameters/typeQueryParam'
        - $ref: '#/components/parameters/nameQueryParam'
        - $ref: '#/components/parameters/localeQueryParam'
        - $ref: '#/components/parameters/screenQueryParam'
      responses:
        '204' :
          description: Successfully deleted.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/ServerError'
  '/branding-preference/text/resolve':
    get:
      tags:
        - Custom Text
      operationId: resolveCustomText
      summary: Resolve custom text of an organization.
      description: |
        This API provides the capability to retrieve the custom text configurations of an organization/specific application.<br>
        If there is no custom text available for the requested locale, API will check for the default locale('en-US') and return it.<br>
        If there is no custom text available for the requested organization, API will check for the parent organization's custom text configurations and return it.<br>
          <b>Permission required:</b> <br>
            * None <br>
          <b>Scope required:</b> <br>
            * None
      parameters:
        - $ref: '#/components/parameters/typeQueryParam'
        - $ref: '#/components/parameters/nameQueryParam'
        - $ref: '#/components/parameters/localeQueryParam'
        - $ref: '#/components/parameters/screenQueryParam'
      responses:
        '200':
          description: OK
          content:
            'application/json':
              schema:
                $ref: '#/components/schemas/ResolvedCustomTextModal'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'

components:
  parameters:
    typeQueryParam:
      in: query
      name: type
      required: false
      description: Type to filter the retrieval of customizations.
      schema:
        type: string
        enum:
          - ORG
          - APP
          - CUSTOM
      example: "ORG"
    nameQueryParam:
      in: query
      name: name
      required: false
      description: Tenant/Application name to filter the retrieval of customizations.
      schema:
        type: string
      example: "WSO2"
    localeQueryParam:
      in: query
      name: locale
      required: false
      description: Locale to filter the retrieval of customizations.
      schema:
        type: string
      example: "en-US"
    screenQueryParam:
      in: query
      name: screen
      required: false
      description: Screen to filter the retrieval of customizations.
      schema:
        type: string
      example: "login"
    restrictToPublishedQueryParam:
      in: query
      name: restrictToPublished
      required: false
      description: |
        Specifies whether to use only published branding preferences for resolving.
        If set to true, branding preference will be resolved only using published branding preferences.
        If set to false, branding preference will be resolved using both published and unpublished branding preferences.
      schema:
        type: boolean
        default: false
      example: true
    operationId:
      in: path
      name: operationId
      required: true
      description: The unique identifier for the branding generation operation.
      schema:
        type: string
      example: "945fa326-bf78-45f6-bfda-c9644650b821"

  schemas:
    BrandingPreferenceModel:
      required:
        - type
        - preference
      type: object
      properties:
        type:
          type: string
          enum:
            - ORG
            - APP
            - CUSTOM
          example: "ORG"
        name:
          type: string
          example: "WSO2"
        locale:
          type: string
          example: "en-US"
          default: "en-US"
        preference:
          type: object
          description: "This is the JSON structured branding preference"
          example: {
            "organizationDetails": {
              "displayName": "Ballerina.io",
              "siteTitle": "Login - Ballerina",
              "copyrightText": "© 2021 WSO2",
              "supportEmail": "support@ballerina.io"
            },
            "images": {
              "logo": {
                "imgURL": "https://ballerina.io/img/ballerina-logo.svg",
                "altText": "Ballerina.io Logo"
              },
              "favicon": {
                "imgURL": "https://central.ballerina.io/favicon.ico"
              }
            },
            "urls": {
              "privacyPolicyURL": "https://ballerina.io/privacy-policy",
              "termsOfUseURL": "https://ballerina.io/terms-of-service/",
              "cookiePolicyURL": "https://ballerina.io/privacy-policy/#cookie-policy"
            },
            "stylesheets": {
              "accountApp": "https://firebasestorage.googleapis.com/v0/b/asgardeo-branding.appspot.com/o/ballerina%2Flogin-portal.overrides.css?alt=media&token=0315462e-534e-4f33-83f9-e4c092d0273d",
              "myAccountApp": "https://asgardeo-branding/user-portal.css"
            },
            "configs": {
              "isBrandingEnabled": true,
              "removeDefaultBranding": false,
              "selfSignUpEnabled": true
            }
          }
    ResolvedBrandingPreferenceModel:
      required:
        - type
        - preference
      type: object
      properties:
        type:
          type: string
          enum:
            - ORG
            - APP
            - CUSTOM
          example: "ORG"
        name:
          type: string
          example: "WSO2"
        locale:
          type: string
          example: "en-US"
          default: "en-US"
        resolvedFrom:
          type: object
          required:
            - type
            - name
          properties:
            type:
              type: string
              enum:
                - ORG
                - APP
                - CUSTOM
              example: "ORG"
            name:
              type: string
              example: "WSO2"
        preference:
          type: object
          description: "This is the JSON structured branding preference"
          example: {
            "organizationDetails": {
              "displayName": "Ballerina.io",
              "siteTitle": "Login - Ballerina",
              "copyrightText": "© 2021 WSO2",
              "supportEmail": "support@ballerina.io"
            },
            "images": {
              "logo": {
                "imgURL": "https://ballerina.io/img/ballerina-logo.svg",
                "altText": "Ballerina.io Logo"
              },
              "favicon": {
                "imgURL": "https://central.ballerina.io/favicon.ico"
              }
            },
            "urls": {
              "privacyPolicyURL": "https://ballerina.io/privacy-policy",
              "termsOfUseURL": "https://ballerina.io/terms-of-service/",
              "cookiePolicyURL": "https://ballerina.io/privacy-policy/#cookie-policy"
            },
            "stylesheets": {
              "accountApp": "https://firebasestorage.googleapis.com/v0/b/asgardeo-branding.appspot.com/o/ballerina%2Flogin-portal.overrides.css?alt=media&token=0315462e-534e-4f33-83f9-e4c092d0273d",
              "myAccountApp": "https://asgardeo-branding/user-portal.css"
            },
            "configs": {
              "isBrandingEnabled": true,
              "removeDefaultBranding": false,
              "selfSignUpEnabled": true
            }
          }
    BrandingGenerationRequestModel:
      type: object
      properties:
        website_url:
          type: string
          description: URL of the organization's website.
          example: "https://wso2.com/"
    BrandingGenerationResponseModel:
      type: object
      properties:
        operation_id:
          type: string
          description: Operation id of the initiated branding generation process.
    BrandingGenerationStatusModel:
      type: object
      properties:
        status:
          type: object
          description: "This is the JSON structured branding preference"
          example: {
            "render_webpage": true,
            "extract_webpage_content": true,
            "webpage_extraction_completed": true,
            "generate_branding": true,
            "branding_generation_status": {
              "color_palette": true,
              "style_properties": true
            },
            "branding_generation_completed_status": {
              "color_palette": false,
              "style_properties": false
            },
            "create_branding_theme": false,
            "branding_generation_completed": false
          }
    BrandingGenerationResultModel:
      type: object
      properties:
        status:
          type: string
          enum:
            - IN_PROGRESS
            - COMPLETED
            - FAILED
          description: The current result of the AI branding operation.
        data:
          type: object
          description: |
            The payload of the response, which varies based on the operation status.
            - For IN_PROGRESS status, an empty JSON object is returned.
            - For COMPLETED status, the `BrandingPreferenceModel` is returned.
            - For FAILED status, an error message is returned.
    CustomTextModel:
      required:
        - type
        - screen
        - preference
      type: object
      properties:
        type:
          type: string
          enum:
            - ORG
            - APP
            - CUSTOM
          example: "ORG"
        name:
          type: string
          example: "WSO2"
        locale:
          type: string
          example: "en-US"
          default: "en-US"
        screen:
          type: string
          example: "login"
        preference:
          type: object
          description: "This is the JSON structured branding preference"
          example: {
            "login": "Sign In",
            "welcome": "Welcome",
            "account.linking": "Account Linking",
            "username": "Username",
            "email.username": "Email address",
            "back.to.sign.in": "Back to Sign In",
            "or": "Or",
            "dont.have.an.account": "Don't have an account?"
          }
    ResolvedCustomTextModal:
      required:
        - type
        - screen
        - preference
      type: object
      properties:
        type:
          type: string
          enum:
            - ORG
            - APP
            - CUSTOM
          example: "ORG"
        name:
          type: string
          example: "WSO2"
        locale:
          type: string
          example: "en-US"
          default: "en-US"
        screen:
          type: string
          example: "login"
        resolvedFrom:
          type: object
          required:
            - type
            - name
          properties:
            type:
              type: string
              enum:
                - ORG
                - APP
                - CUSTOM
              example: "ORG"
            name:
              type: string
              example: "WSO2"
        preference:
          type: object
          description: "This is the JSON structured branding preference"
          example: {
            "login": "Sign In",
            "welcome": "Welcome",
            "account.linking": "Account Linking",
            "username": "Username",
            "email.username": "Email address",
            "back.to.sign.in": "Back to Sign In",
            "or": "Or",
            "dont.have.an.account": "Don't have an account?"
          }
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          example: BPM-60001
        message:
          type: string
          example: Some Error Message
        description:
          type: string
          example: Some Error Description
        traceId:
          type: string
          example: 3erfee-232-efewv-2321-43ferfe24r

  #-----------------------------------------------------
  # Descriptions of Branding Preference API responses.
  #-----------------------------------------------------
  responses:
    BadRequest:
      description: Invalid input in the request.
      content:
        'application/json':
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication information is missing or invalid.
    Forbidden:
      description: Access forbidden.
    NotFound:
      description: Requested resource is not found.
      content:
        'application/json':
          schema:
            $ref: '#/components/schemas/Error'
    Conflict:
      description: Conflict.
      content:
        'application/json':
          schema:
            $ref: '#/components/schemas/Error'
    ServerError:
      description: Internal server error.
      content:
        'application/json':
          schema:
            $ref: '#/components/schemas/Error'
    NotImplemented:
      description: Not Implemented.
      content:
        'application/json':
          schema:
            $ref: '#/components/schemas/Error'

  #-----------------------------------------------------
  # Applicable authentication mechanisms.
  #-----------------------------------------------------
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: 'https://localhost:9443/oauth2/authorize'
          tokenUrl: 'https://localhost:9443/oauth2/token'
          scopes: {}
