openapi: 3.0.0
info:
  version: "0.1.1"
  title: "OpenAPI Specification: Merchant Product Submission API"
  description: This service allows merchants to create their assortment in Zalando systems.
    Platform.
  x-audience: external-merchant
  x-api-id: 49e51b92-1b36-447f-adb1-be1305faaea6
paths:
  /merchants/{merchant_id}/product-submissions:
    post:
      summary: Submits a product for creation
      description: |
        Post a new Product Submission. A successful response to a product submission does not guarantee that the product
        will be created. Due to Zalando's high standards for data quality, each product must pass through multiple
        layers of both automatic and manual validation after submission. Should a product fail validation, you can
        resubmit a corrected version of the product data, which trigger a new validation process. The validation status
        may be fetched using another API ("Product Details").
      tags:
        - Product Submissions
      security:
        - OAuth2: [products/write]
      parameters:
        - name: merchant_id
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/MerchantId'
      requestBody:
        description: A JSON representation of the product to be forwarded to Zalando's validation
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductSubmission"
      responses:
        '200':
          $ref: '#/components/responses/SuccessResponse'
        '400':
          $ref: '#/components/responses/FailResponse'
        default:
          $ref: '#/components/responses/ProblemResponse'
components:
  responses:
    FailResponse:
      description: |
        Request body is not well formed, or enforced validation rules have not been satisfied.
        A failure includes body_errors (enforced errors) and possibly body_warnings (unenforced errors)
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: 'https://opensource.zalando.com/problem/schema.yaml#/Problem'
              - $ref: '#/components/schemas/SubmissionProblem'
          examples:
            errors_without_warnings:
              value:
                {
                  "title": "Failure",
                  "detail": "Bad Request: decoding or structural errors found",
                  "code": 400,
                  "body_errors": [
                    {
                      "path": "",
                      "attribute": "outline",
                      "message": "outline is missing",
                      "reason": "INVALID_STRUCTURE",
                      "reference": "https://developers.merchants.zalando.com/docs/onboarding-new-products.html#key-concepts"
                    }
                  ]
                }
            errors_with_warnings:
              value:
                {
                  "title": "Failure",
                  "detail": "Bad Request: validation errors found",
                  "code": 400,
                  "body_errors": [
                    {
                      "path": "product_model/product_configs/0/product_config_attributes/season_code",
                      "expected": "String",
                      "actual": "Undefined"
                    }
                  ],
                  "body_warnings": [
                    {
                      "path": "/outline",
                      "tier": "",
                      "attribute": "outline",
                      "message": "outline test is invalid for merchant 19e3bdc5-4402-4c34-89a6-b79824420799",
                      "reason": "INVALID_OUTLINE",
                      "reference": "https://developers.merchants.zalando.com/docs/onboarding-new-products.html#key-concepts"
                    }
                  ]
                }

    SuccessResponse:
      description: |
        The submission was successfully accepted for processing in the onboarding pipeline.
        It may included body_warnings consisting of unenforced validation rules.
      content:
        application/json:
          schema:
            type: object
            properties:
              title:
                type: string
              status:
                type: integer
                format: int32
              detail:
                type: string
              body_warnings:
                description: unenforced errors that do not affect the submission acceptance.
                type: array
                items:
                  $ref: '#/components/schemas/ValidationError'
          examples:
            success_without_warnings:
              value:
                {}
            success_with_warnings:
              value:
                {
                  "title": "Success",
                  "status": 200,
                  "detail": "Ok with warnings",
                  "body_warnings": [
                    {
                      "attribute": "merchant_product_model_id",
                      "tier": "model",
                      "path": "/product_model/merchant_product_model_id",
                      "message": "merchant_product_model_id is empty",
                      "reason": "INVALID_IDENTIFIER",
                      "reference": "https://developers.merchants.zalando.com/docs/onboarding-new-products.html#key-concepts"
                    }
                  ]
                }

    ProblemResponse:
      description: error occurred - see status code and problem object for more information.
      content:
        "application/problem+json":
          schema:
            $ref: 'https://opensource.zalando.com/problem/schema.yaml#/Problem'

  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    BodyErrors:
      description: errors that lead to submission not being accepted.
      type: array
      items:
        $ref: '#/components/schemas/ValidationError'

    BodyWarnings:
      description: unenforced errors that do not affect the submission acceptance.
      type: array
      items:
        $ref: '#/components/schemas/ValidationError'

    SubmissionProblem:
      type: object
      properties:
        body_errors:
          $ref: '#/components/schemas/BodyErrors'
        body_warnings:
          $ref: '#/components/schemas/BodyWarnings'

    MerchantId:
      type: string
      format: uuid
      example: 169dbd29-4d08-4943-a005-3749d5dd8232

    MerchantModelId:
      description: |
        An identifier the merchant can use for referring to the product model in our systems
      type: string
      example: 47812AAS

    MerchantConfigId:
      description: An identifier the merchant can use for referring to the product config in our systems
      type: string
      example: 411212

    MerchantSimpleId:
      description: An identifier the merchant can use for referring to the product simple in our systems
      type: string
      example: WTC741

    ProductSimpleAttributes:
      type: object
      description: |
        The attributes at the simple tier can vary according to the specific merchant and the outline of the product.
        This can be determined by querying the Merchant Attributes API.
      example: {
        "ean": "4038671015234",
        "size_codes": {
          "size": "XL"
        }
      }

    ProductSimple:
      type: object
      required:
        - merchant_product_simple_id
        - product_simple_attributes
      properties:
        merchant_product_simple_id:
          $ref: '#/components/schemas/MerchantSimpleId'
        product_simple_attributes:
          $ref: '#/components/schemas/ProductSimpleAttributes'

    ProductSimples:
      type: array
      items:
        $ref: '#/components/schemas/ProductSimple'

    ProductConfigAttributes:
      type: object
      description: |
        The attributes at the config tier can vary according to the specific merchant and the outline of the product.
        This can be determined by querying the Merchant Attributes API.
      example: {
        "color_code": "802",
        "season_code": "fs18",
        "media": [{"url": "https://zalando.com/1667531.jpg", "sort_key": 1}]
      }

    ProductConfig:
      required:
        - merchant_product_config_id
        - product_config_attributes
        - product_simples
      properties:
        merchant_product_config_id:
          $ref: '#/components/schemas/MerchantConfigId'
        product_config_attributes:
          $ref: '#/components/schemas/ProductConfigAttributes'
        product_simples:
          $ref: '#/components/schemas/ProductSimples'

    ProductConfigs:
      type: array
      items:
        $ref: '#/components/schemas/ProductConfig'

    ProductModel:
      type: object
      required:
        - merchant_product_model_id
        - product_model_attributes
        - product_configs
      properties:
        merchant_product_model_id:
          $ref: '#/components/schemas/MerchantModelId'
        product_model_attributes:
          $ref: '#/components/schemas/ProductModelAttributes'
        product_configs:
          $ref: '#/components/schemas/ProductConfigs'

    ProductModelAttributes:
      type: object
      description: |
        The attributes at the model tier can vary according to the specific merchant and the outline of the product.
        This can be determined by querying the Merchant Attributes API.
      example: {
        "name": "New Fancy Product 2.0",
        "brand_code": "5FX",
        "size_group": {
          "size": "2MAE000A2A"
        },
        "target_age_groups": ["target_age_group_kid", "target_age_group_baby"],
        "target_genders": ["target_gender_female", "target_gender_male"]
      }

    Outline:
      description: outline id (aka silhouette id)
      type: string
      example: ankle_boots

    ProductSubmission:
      description: |
        Product Submission is an attempt to create a product in Zalando systems.
      required:
        - product_model
        - outline
      properties:
        outline:
          $ref: '#/components/schemas/Outline'
        product_model:
          $ref: '#/components/schemas/ProductModel'

    Attribute:
      type: string
      example: shoe_width
      description: the label of the merchant attribute

    Message:
      type: string
      description: |
        A human readable description of the error.
        It should not contain double quotes ("), but may contain single quotes (').
      example: "skirt_details contains a boolean value but should contain only string values"

    Tier:
      type: string
      description: |
        an empty value indicates that the error is at the root level of the document (above model).
      enum:
        - ""
        - "model"
        - "config"
        - "simple"

    Path:
      description: |
        RFC 6901 JSON pointer to the property causing the error.
        It represents the location in the submitted json document.
        It starts with a /, and path components are separated by forward slashes.
        Array Elements are denoted by numbers, for example /0 denotes the first element
        in the array.
        The path of  "/" points to the root.
        The path of "" indicates that the error/warning is related to the entire document
        (for example if the document could not be decoded to Json).
      type: string
      format: jsonpointer
      pattern: '^(/(([A-Za-z_][A-Za-z_\d]*)|(\d+)))+$'
      example: /product_model/product_configs/3/product_config_attributes/material

    Reason:
      type: string
      description: |
        A short identifier of the kind of the error.
        It does not contain spaces.
      pattern: '^[a-z-]+$'
      example: INVALID_FORMAT

    Reference:
      type: string
      format: uri
      description: |
        An absolute URI that points to human-readable documentation of the error.
        It should be accessible to external users.
      example: https://developers.merchants.zalando.com/docs/onboarding-new-products.html#key-concepts

    ValidationError:
      properties:
        attribute:
          $ref: '#/components/schemas/Attribute'
        path:
          $ref: '#/components/schemas/Path'
        message:
          $ref: '#/components/schemas/Message'
        reason:
          $ref: '#/components/schemas/Reason'
        reference:
          $ref: '#/components/schemas/Reference'
        tier:
          $ref: '#/components/schemas/Tier'
      example:
        invalidIdentifierError:
          value:
            - {
              "attribute": "merchant_product_model_id",
              "tier": "model",
              "path": "/product_model/merchant_product_model_id",
              "message": "merchant_product_model_id is empty",
              "reason": "INVALID_IDENTIFIER",
              "reference": "https://developers.merchants.zalando.com/docs/onboarding-new-products.html#key-concepts"
            }
        invalidValueError:
          value:
            - {
              "path": "/product_model/merchant_product_model_id",
              "tier": "model",
              "attribute": "merchant_product_model_id",
              "message": "merchant_product_model_id is empty",
              "reason": "UNSUPPORTED_VALUE",
              "reference": "https://developers.merchants.zalando.com/docs/onboarding-new-products.html#key-concepts"
            }
