{
  "openapi": "3.1.0",
  "info": {
    "title": "Importivity API",
    "version": "1.0.0",
    "summary": "Public, read-only API for AI agents working with Importivity, a US product sourcing and manufacturing company.",
    "description": "Importivity finds, vets and manages factories in China, Vietnam, Mexico, India and the US for US brands, and delivers goods duty-paid to their door. This API lets an agent read what Importivity does, estimate landed cost and tooling decisions, find guides and case studies, and give a person a pre-filled sourcing request link.\n\nNo authentication. Read-only: nothing here sends a request, an email or an order. Limit: 60 requests per minute per IP address per endpoint. Every response carries RateLimit-Policy, RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers; a 429 also carries Retry-After. Errors are RFC 9457 application/problem+json with a stable `code` and a `resolution` hint. Any page on the site is also available as Markdown by sending `Accept: text/markdown`.\n\nVersioning: the version is in the path (/api/v1). Fields may be added to v1 responses at any time; nothing is removed or renamed within v1. A breaking change ships as /api/v2, and v1 keeps answering for at least 90 days after that, with `Deprecation` and `Sunset` headers on its responses for the whole window and the dates posted on the docs page. Deprecation policy: https://importivity.com/developers/#versioning-and-deprecation",
    "contact": {
      "name": "Importivity",
      "url": "https://importivity.com/contact/"
    },
    "termsOfService": "https://importivity.com/terms-and-conditions/"
  },
  "externalDocs": {
    "description": "API and agent docs",
    "url": "https://importivity.com/developers/"
  },
  "servers": [
    {
      "url": "https://importivity.com"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Company",
      "description": "What Importivity does and has done."
    },
    {
      "name": "Content",
      "description": "Guides and pages from the site."
    },
    {
      "name": "Calculators",
      "description": "Cost estimates from your own inputs."
    },
    {
      "name": "Requests",
      "description": "Starting a sourcing request with a person in the loop."
    }
  ],
  "paths": {
    "/api/v1/services/": {
      "get": {
        "operationId": "listServices",
        "tags": [
          "Company"
        ],
        "summary": "List Importivity's services",
        "description": "Every service Importivity offers (product sourcing, manufacturer sourcing, quality control, prototyping, packaging, freight, reshoring and more) with a one-line tagline, a summary, the main steps and the page URL. Call this to explain what Importivity can do for a user or to pick the right page to link.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to look for in service names and summaries. Every word must match. Leave out to list all.",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "quality"
          }
        ],
        "responses": {
          "200": {
            "description": "The services.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Service"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/case-studies/": {
      "get": {
        "operationId": "listCaseStudies",
        "tags": [
          "Company"
        ],
        "summary": "List client case studies and their results",
        "description": "Real client programs with the measured result of each and a page to cite. Use it when a user asks whether Importivity has done something similar before.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to look for in client names and results. Every word must match. Leave out to list all.",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "tariff"
          }
        ],
        "responses": {
          "200": {
            "description": "The case studies.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseStudy"
                      }
                    },
                    "more": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/articles/": {
      "get": {
        "operationId": "searchArticles",
        "tags": [
          "Content"
        ],
        "summary": "Search sourcing and tariff guides",
        "description": "Searches Importivity's blog, newest first. Every word in `q` must appear in the title or summary. Leave `q` out to list everything. Use it to find a guide on a sourcing, manufacturing, tariff or import question and link the user to it.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to search for in titles and summaries.",
            "schema": {
              "type": "string",
              "description": "Search words, for example `tariff vietnam`.",
              "maxLength": 100
            },
            "example": "alibaba scams"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page of results.",
            "schema": {
              "type": "integer",
              "description": "Page number, from 1.",
              "minimum": 1,
              "maximum": 1000,
              "default": 1
            }
          },
          {
            "name": "perPage",
            "in": "query",
            "required": false,
            "description": "Results per page, at most 50.",
            "schema": {
              "type": "integer",
              "description": "Results per page.",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching articles.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Article"
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "perPage": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer",
                      "description": "Matches across all pages."
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/faq/": {
      "get": {
        "operationId": "listFaq",
        "tags": [
          "Company"
        ],
        "summary": "Answers to common buyer questions",
        "description": "Importivity's approved answers on what happens after a request, whether it is a factory or an agent, what the quote includes, who the importer of record is, minimums, samples, lead times, NDAs and tooling ownership, quality checks and buyers outside the US. Quote these answers rather than guessing.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to look for in questions and answers. Every word must match. Leave out to list all.",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "importer of record"
          }
        ],
        "responses": {
          "200": {
            "description": "The questions and answers.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FaqItem"
                      }
                    },
                    "more": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/landed-cost/": {
      "get": {
        "operationId": "estimateLandedCost",
        "tags": [
          "Calculators"
        ],
        "summary": "Estimate landed cost per unit",
        "description": "Adds freight, import duty, cargo insurance and other fees to the factory price and returns the total and the landed cost per unit, in US dollars. Optional inputs default to 0. This is arithmetic on your inputs, not a quote; for real prices use createQuoteRequestLink.",
        "parameters": [
          {
            "name": "unitCost",
            "in": "query",
            "required": true,
            "description": "Factory (FOB or EXW) price per unit in US dollars.",
            "schema": {
              "type": "number",
              "description": "Factory price per unit, USD.",
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 8
          },
          {
            "name": "quantity",
            "in": "query",
            "required": true,
            "description": "Number of units.",
            "schema": {
              "type": "integer",
              "description": "Units in the order.",
              "minimum": 1,
              "maximum": 100000000
            },
            "example": 1000
          },
          {
            "name": "freight",
            "in": "query",
            "required": false,
            "description": "Total freight cost for the order in US dollars.",
            "schema": {
              "type": "number",
              "description": "Total freight, USD.",
              "minimum": 0,
              "default": 0
            },
            "example": 2400
          },
          {
            "name": "dutyRate",
            "in": "query",
            "required": false,
            "description": "Import duty as a percent of goods value, all tariffs combined (for example 10 for 10%).",
            "schema": {
              "type": "number",
              "description": "Duty rate, percent of goods value.",
              "minimum": 0,
              "maximum": 1000,
              "default": 0
            },
            "example": 10
          },
          {
            "name": "insuranceRate",
            "in": "query",
            "required": false,
            "description": "Cargo insurance as a percent of goods plus freight.",
            "schema": {
              "type": "number",
              "description": "Cargo insurance, percent.",
              "minimum": 0,
              "maximum": 100,
              "default": 0
            },
            "example": 0.5
          },
          {
            "name": "otherFees",
            "in": "query",
            "required": false,
            "description": "Customs broker and other fixed fees for the order, in US dollars.",
            "schema": {
              "type": "number",
              "description": "Other fees, USD.",
              "minimum": 0,
              "default": 0
            },
            "example": 350
          }
        ],
        "responses": {
          "200": {
            "description": "The breakdown.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LandedCost"
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/oem-vs-odm/": {
      "get": {
        "operationId": "compareOemOdm",
        "tags": [
          "Calculators"
        ],
        "summary": "Compare own tooling (OEM) with a factory design (ODM)",
        "description": "For an injection-molded part: the per-unit and total cost of paying for your own mold (OEM) against buying a factory's existing design at a premium (ODM), and the quantity where your own mold becomes cheaper.",
        "parameters": [
          {
            "name": "quantity",
            "in": "query",
            "required": true,
            "description": "Order quantity.",
            "schema": {
              "type": "integer",
              "description": "Units.",
              "minimum": 1,
              "maximum": 2000000
            },
            "example": 5000
          },
          {
            "name": "tooling",
            "in": "query",
            "required": false,
            "description": "One-time tooling (mold) cost in US dollars.",
            "schema": {
              "type": "number",
              "description": "Mold cost, USD.",
              "minimum": 0,
              "default": 15000
            },
            "example": 15000
          },
          {
            "name": "premium",
            "in": "query",
            "required": false,
            "description": "Percent the factory adds to the piece price for its own design.",
            "schema": {
              "type": "number",
              "description": "ODM premium, percent.",
              "minimum": 0,
              "maximum": 500,
              "default": 20
            },
            "example": 20
          }
        ],
        "responses": {
          "200": {
            "description": "The comparison.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OemOdm"
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/quote-request-link/": {
      "get": {
        "operationId": "createQuoteRequestLink",
        "tags": [
          "Requests"
        ],
        "summary": "Get a pre-filled sourcing request link for a person",
        "description": "Builds a link to Importivity's request form with the product brief already filled in. Give the link to the person you are helping; they confirm with a code sent to their email and a person on Importivity's team replies within one business day. Calling this sends nothing. Use it when a user wants a factory quote, samples or production for a product.",
        "parameters": [
          {
            "name": "product",
            "in": "query",
            "required": true,
            "description": "The product in plain words, with material or key specs if known.",
            "schema": {
              "type": "string",
              "description": "What to make or source.",
              "minLength": 2,
              "maxLength": 300
            },
            "example": "Insulated stainless steel tumbler, 20 oz, custom logo"
          },
          {
            "name": "quantity",
            "in": "query",
            "required": false,
            "description": "How many units for the first order.",
            "schema": {
              "type": "integer",
              "description": "Units.",
              "minimum": 1
            },
            "example": 5000
          },
          {
            "name": "targetPrice",
            "in": "query",
            "required": false,
            "description": "The price per unit the person hopes to pay, in US dollars.",
            "schema": {
              "type": "number",
              "description": "Target price per unit, USD.",
              "minimum": 0
            },
            "example": 4.5
          },
          {
            "name": "link",
            "in": "query",
            "required": false,
            "description": "A listing or page showing the product or something close to it.",
            "schema": {
              "type": "string",
              "description": "Reference product URL.",
              "format": "uri",
              "maxLength": 500
            }
          },
          {
            "name": "details",
            "in": "query",
            "required": false,
            "description": "Other details: packaging, certifications, timeline, destination.",
            "schema": {
              "type": "string",
              "description": "Anything else.",
              "maxLength": 1500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The link and the brief it carries.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteLink"
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/markdown/": {
      "get": {
        "operationId": "getPageMarkdown",
        "tags": [
          "Content"
        ],
        "summary": "Get any page on the site as Markdown",
        "description": "Returns the main content of an importivity.com page as Markdown with a YAML header (title, description, url). Same result as requesting the page itself with `Accept: text/markdown`. Unknown paths return 404 with a Markdown body.",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "The page path, for example /how-it-works/ or /blog/does-alibaba-have-scams/.",
            "schema": {
              "type": "string",
              "description": "Page path starting with /.",
              "maxLength": 1024
            },
            "example": "/how-it-works/"
          }
        ],
        "responses": {
          "200": {
            "description": "The page as Markdown.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            },
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "No page at that path. The body is Markdown with links to the site map.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "default": {
            "description": "An RFC 9457 problem with a stable `code` and a `resolution` hint.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "headers": {
      "RateLimit-Policy": {
        "description": "The limit and its window in seconds, for example `60;w=60`.",
        "schema": {
          "type": "string"
        }
      },
      "RateLimit-Limit": {
        "description": "Requests allowed per window.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Remaining": {
        "description": "Requests left in the current window.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Reset": {
        "description": "Seconds until a request slot frees up.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "Problem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "resolution"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "Link to the docs for this error."
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "code": {
            "type": "string",
            "enum": [
              "invalid_parameter",
              "not_found",
              "method_not_allowed",
              "rate_limited",
              "upstream_unavailable"
            ]
          },
          "detail": {
            "type": "string",
            "description": "What went wrong with this request."
          },
          "resolution": {
            "type": "string",
            "description": "What to do next."
          }
        }
      },
      "Service": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "summary",
          "url"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "group": {
            "type": "string"
          },
          "tagline": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "CaseStudy": {
        "type": "object",
        "required": [
          "name",
          "result",
          "url"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "result": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Article": {
        "type": "object",
        "required": [
          "title",
          "url"
        ],
        "properties": {
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "published": {
            "type": "string",
            "description": "Publish date, ISO 8601."
          },
          "updated": {
            "type": "string",
            "description": "Last update, ISO 8601."
          }
        }
      },
      "FaqItem": {
        "type": "object",
        "required": [
          "id",
          "question",
          "answer"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "question": {
            "type": "string"
          },
          "answer": {
            "type": "string"
          }
        }
      },
      "LandedCost": {
        "type": "object",
        "required": [
          "currency",
          "total",
          "perUnit"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "const": "USD"
          },
          "input": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "goods": {
            "type": "number"
          },
          "freight": {
            "type": "number"
          },
          "duty": {
            "type": "number"
          },
          "insurance": {
            "type": "number"
          },
          "otherFees": {
            "type": "number"
          },
          "total": {
            "type": "number"
          },
          "perUnit": {
            "type": "number",
            "description": "Landed cost per unit."
          },
          "costOverGoodsPercent": {
            "type": "number",
            "description": "How much freight, duty, insurance and fees add, as a percent of goods value."
          },
          "formula": {
            "type": "string"
          },
          "note": {
            "type": "string"
          },
          "calculator": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "OemOdm": {
        "type": "object",
        "required": [
          "currency",
          "oem",
          "odm",
          "cheaper"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "const": "USD"
          },
          "input": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "oem": {
            "type": "object",
            "properties": {
              "unitPrice": {
                "type": "number"
              },
              "toolingPerUnit": {
                "type": "number"
              },
              "allInPerUnit": {
                "type": "number"
              },
              "total": {
                "type": "number"
              }
            }
          },
          "odm": {
            "type": "object",
            "properties": {
              "unitPrice": {
                "type": "number"
              },
              "total": {
                "type": "number"
              }
            }
          },
          "cheaper": {
            "type": "string",
            "enum": [
              "oem",
              "odm"
            ]
          },
          "crossoverQuantity": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Quantity from which own tooling is cheaper; null if not below 2,000,000."
          },
          "basis": {
            "type": "string"
          },
          "calculator": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "QuoteLink": {
        "type": "object",
        "required": [
          "url",
          "brief"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Give this to the person. Opening it starts their request."
          },
          "brief": {
            "type": "string",
            "description": "The text the request starts with."
          },
          "nextSteps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}