{
  "openapi": "3.1.0",
  "info": {
    "title": "HPH Integrations Material Catalog Item search",
    "version": "v1",
    "description": "HPH Integrations public API v1. Available to the Customer Testing group; not available in Production."
  },
  "paths": {
    "/v1/catalog/items/search": {
      "get": {
        "operationId": "SearchMaterialCatalogItems",
        "x-runtime-status": "testing-available",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["company", "hph"] },
            "description": "Which catalog to search: the represented Company's Material Catalog, or the HPH catalog. There is no automatic fallback."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "minLength": 2, "maxLength": 256 },
            "description": "Free-text search over item descriptions."
          },
          {
            "name": "company_item_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "minLength": 1, "maxLength": 255 },
            "description": "Exact company item identifier. Allowed only with source=company."
          },
          {
            "name": "hph_item_code",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "pattern": "^[0-9A-Z]{6,10}$" },
            "description": "Exact HPH Item Code. Allowed only with source=hph."
          },
          {
            "name": "identifier_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["upc", "gtin", "manufacturer_part_number", "manufacturer_order_number"]
            },
            "description": "Portable identifier type. Must be sent together with identifier_value."
          },
          {
            "name": "identifier_value",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "minLength": 1, "maxLength": 255 },
            "description": "Portable identifier value. A upc is 12 digits and a gtin 14 digits, each with a valid check digit."
          },
          {
            "name": "manufacturer",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "minLength": 2, "maxLength": 200 },
            "description": "Manufacturer refinement."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "minLength": 1, "maxLength": 200 },
            "description": "Category refinement."
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "enum": [10, 25, 50], "default": 10 },
            "description": "Items per page."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^\\S+$" },
            "description": "Opaque next_cursor from the previous page of the same search."
          }
        ],
        "x-request-rules": [
          "Every parameter appears at most once; unknown parameters are rejected.",
          "At least one of q, company_item_id, hph_item_code, identifier_type/identifier_value, manufacturer or category is required: browsing the whole catalog is not allowed.",
          "company_item_id requires source=company; hph_item_code requires source=hph.",
          "identifier_type and identifier_value are sent together or not at all."
        ],
        "responses": {
          "200": {
            "description": "One bounded page of results from the selected catalog.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MaterialCatalogSearchResponseV1" },
                "example": {
                  "contract_version": "v1",
                  "search_reference": "search_c3ludGhldGljLXNlYXJjaC1yZWZlcmVu",
                  "outcome": "results",
                  "source": "company",
                  "count": { "relation": "exact", "value": 1 },
                  "items": [
                    {
                      "item_type": "company_item",
                      "item_skey": "5f0e8a3c-2b1d-4c6e-9a7f-0123456789ab",
                      "company_item_id": "ACME-1001",
                      "descriptions": [
                        { "value": "Synthetic 1/2 in. copper coupling", "provenance": "effective_catalog" }
                      ],
                      "manufacturer_name": "Synthetic Manufacturing",
                      "manufacturer_part_number": "SYN-CPL-050"
                    }
                  ]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/CursorStale" },
          "429": { "$ref": "#/components/responses/QuotaExceeded" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "MaterialCatalogSearchResponseV1": {
        "type": "object",
        "additionalProperties": false,
        "required": ["contract_version", "search_reference", "outcome", "source", "count", "items"],
        "properties": {
          "contract_version": { "type": "string", "const": "v1" },
          "search_reference": { "type": "string", "pattern": "^search_[A-Za-z0-9_-]{32}$" },
          "outcome": { "type": "string", "enum": ["results", "no_results", "ambiguous_exact_identity"] },
          "source": { "type": "string", "enum": ["company", "hph"] },
          "count": { "$ref": "#/components/schemas/MaterialCatalogSearchCountV1" },
          "items": {
            "type": "array",
            "maxItems": 50,
            "items": { "$ref": "#/components/schemas/MaterialCatalogSearchItemV1" }
          },
          "next_cursor": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "Present only when another page exists."
          }
        }
      },
      "MaterialCatalogSearchCountV1": {
        "type": "object",
        "additionalProperties": false,
        "required": ["relation", "value"],
        "properties": {
          "relation": { "type": "string", "enum": ["exact", "at_least", "unavailable"] },
          "value": { "type": ["integer", "null"], "minimum": 0 }
        }
      },
      "CompanyMaterialCatalogSearchDescriptionV1": {
        "type": "object",
        "additionalProperties": false,
        "required": ["value", "provenance"],
        "properties": {
          "value": { "type": "string" },
          "provenance": { "type": "string", "const": "effective_catalog" }
        }
      },
      "HphMaterialCatalogSearchDescriptionV1": {
        "type": "object",
        "additionalProperties": false,
        "required": ["value", "provenance"],
        "properties": {
          "value": { "type": "string" },
          "provenance": { "type": "string", "const": "hph_authored" }
        }
      },
      "MaterialCatalogSearchItemV1": {
        "oneOf": [
          { "$ref": "#/components/schemas/CompanyMaterialCatalogSearchItemV1" },
          { "$ref": "#/components/schemas/HphMaterialCatalogSearchItemV1" }
        ],
        "discriminator": {
          "propertyName": "item_type",
          "mapping": {
            "company_item": "#/components/schemas/CompanyMaterialCatalogSearchItemV1",
            "hph_item": "#/components/schemas/HphMaterialCatalogSearchItemV1"
          }
        }
      },
      "CompanyMaterialCatalogSearchItemV1": {
        "type": "object",
        "additionalProperties": false,
        "required": ["item_type", "item_skey", "descriptions"],
        "properties": {
          "item_type": { "type": "string", "const": "company_item" },
          "item_skey": { "type": "string", "format": "uuid" },
          "company_item_id": { "type": "string" },
          "descriptions": {
            "type": "array",
            "maxItems": 8,
            "items": { "$ref": "#/components/schemas/CompanyMaterialCatalogSearchDescriptionV1" }
          },
          "manufacturer_name": { "type": "string" },
          "manufacturer_part_number": { "type": "string" },
          "manufacturer_order_number": { "type": "string" },
          "upc": { "type": "string" },
          "gtin": { "type": "string" }
        }
      },
      "HphMaterialCatalogSearchItemV1": {
        "type": "object",
        "additionalProperties": false,
        "required": ["item_type", "hph_item_code", "descriptions"],
        "properties": {
          "item_type": { "type": "string", "const": "hph_item" },
          "hph_item_code": { "type": "string", "pattern": "^[0-9A-Z]{6,10}$" },
          "descriptions": {
            "type": "array",
            "maxItems": 8,
            "items": { "$ref": "#/components/schemas/HphMaterialCatalogSearchDescriptionV1" }
          },
          "manufacturer_name": { "type": "string" },
          "manufacturer_part_number": { "type": "string" },
          "manufacturer_order_number": { "type": "string" },
          "upc": { "type": "string" },
          "gtin": { "type": "string" }
        }
      },
      "StableProblemV1": { "type": "object", "additionalProperties": false, "required": ["type", "title", "status", "code", "correlation_id", "retryable", "errors"], "description": "Problem details as sent on the wire (application/problem+json). Field names are snake_case, like every other request and response body.", "properties": { "type": { "type": "string", "format": "uri" }, "title": { "type": "string" }, "status": { "type": "integer" }, "code": { "type": "string" }, "correlation_id": { "type": "string" }, "retryable": { "type": "boolean" }, "errors": { "type": ["object", "null"], "additionalProperties": { "type": "array", "items": { "type": "string" } } } } }
    },
    "responses": {
      "BadRequest": {
        "description": "INVALID_MATERIAL_CATALOG_SEARCH: the query string breaks a request rule.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/StableProblemV1" } } }
      },
      "Unauthorized": {
        "description": "Authentication failed.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/StableProblemV1" } } }
      },
      "Forbidden": {
        "description": "MATERIAL_CATALOG_SEARCH_NOT_AUTHORIZED: current Enterprise and represented-company authority are required.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/StableProblemV1" } } }
      },
      "NotFound": {
        "description": "MATERIAL_CATALOG_SEARCH_NOT_FOUND: the represented company or catalog was not found or is concealed.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/StableProblemV1" } } }
      },
      "CursorStale": {
        "description": "MATERIAL_CATALOG_SEARCH_CURSOR_STALE: the catalog changed while paging; restart the search without a cursor.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/StableProblemV1" } } }
      },
      "QuotaExceeded": {
        "description": "QUOTA_EXCEEDED: the search quota is unavailable.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/StableProblemV1" } } }
      },
      "Unavailable": {
        "description": "MATERIAL_CATALOG_SEARCH_UNAVAILABLE: temporarily unavailable; the problem says whether a retry may succeed.",
        "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/StableProblemV1" } } }
      }
    }
  }
}
