{
  "openapi": "3.1.0",
  "info": {
    "title": "Print Peppermint — Quote Desk for AI agents",
    "version": "1.0.0",
    "description": "Print Peppermint is a specialty print studio (business cards, letterpress, foil, edge painting, invitations, stationery, packaging, rigid boxes, metal and NFC cards), shipping to 30+ countries. Use `talk_to_studio` to describe what your human needs in plain language. Our studio agent will advise on specs and ask only what it needs. When it says the brief is ready, call `submit_quote_request` with your human's name and email and their consent. A specialist replies with priced options (usually within one business day, often within hours), a product render, and a checkout link. Poll `get_quote_status` or pass a `callback_url`. Checkout and proof approval are completed by the human."
  },
  "externalDocs": {
    "url": "https://www.printpeppermint.com/agents"
  },
  "servers": [
    {
      "url": "https://www.printpeppermint.com/api/public/agent-desk/v1"
    }
  ],
  "paths": {
    "/get_studio_capabilities": {
      "get": {
        "operationId": "get_studio_capabilities",
        "summary": "Get studio capabilities",
        "description": "What we make and how: product families, papers, finishes, turnaround, shipping, starting-from anchors and artwork rules.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown conversation_token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/talk_to_studio": {
      "post": {
        "operationId": "talk_to_studio",
        "summary": "Talk to the studio desk",
        "description": "Describe the job in plain language. Our studio agent advises on the spec, asks only what matters, and says when the brief is ready to submit. The first call returns a conversation_token once.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown conversation_token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "conversation_token": {
                    "description": "Bearer token returned once by the first talk_to_studio call.",
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 200
                  },
                  "agent_client": {
                    "description": "Self-reported client name, e.g. claude-desktop.",
                    "type": "string",
                    "maxLength": 100
                  },
                  "principal": {
                    "type": "object",
                    "properties": {
                      "company": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "name": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "email": {
                        "type": "string",
                        "maxLength": 255,
                        "format": "email",
                        "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                      }
                    }
                  }
                },
                "required": [
                  "message"
                ]
              }
            }
          }
        }
      }
    },
    "/attach_artwork": {
      "post": {
        "operationId": "attach_artwork",
        "summary": "Attach artwork",
        "description": "Attach a file by public https URL (pdf, ai, eps, svg, png, jpg, webp, heic, tif, psd, zip; 50 MB max, 10 per conversation). We rehost it.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown conversation_token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "conversation_token": {
                    "description": "Bearer token returned once by the first talk_to_studio call.",
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 200
                  },
                  "file_url": {
                    "type": "string",
                    "maxLength": 2000,
                    "format": "uri"
                  },
                  "file_name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "required": [
                  "conversation_token",
                  "file_url"
                ]
              }
            }
          }
        }
      }
    },
    "/submit_quote_request": {
      "post": {
        "operationId": "submit_quote_request",
        "summary": "Submit quote request",
        "description": "Submit the brief as a real quote request on behalf of your human. Requires principal name, email and principal_consent: true. Idempotent per conversation.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown conversation_token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "conversation_token": {
                    "description": "Bearer token returned once by the first talk_to_studio call.",
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 200
                  },
                  "principal": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "email": {
                        "type": "string",
                        "maxLength": 255,
                        "format": "email",
                        "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                      },
                      "company": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "phone": {
                        "type": "string",
                        "maxLength": 30
                      }
                    },
                    "required": [
                      "name",
                      "email"
                    ]
                  },
                  "principal_consent": {
                    "description": "Your human asked for this quote and agreed to be contacted by email.",
                    "type": "boolean",
                    "const": true
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "callback_url": {
                    "description": "Optional https webhook for quote.message and quote.status events.",
                    "type": "string",
                    "maxLength": 2000,
                    "format": "uri"
                  }
                },
                "required": [
                  "conversation_token",
                  "principal",
                  "principal_consent"
                ]
              }
            }
          }
        }
      }
    },
    "/get_quote_status": {
      "post": {
        "operationId": "get_quote_status",
        "summary": "Get quote status",
        "description": "Status, priced options and tiers, customer-visible messages (with render attachments), the checkout link for your human, and the next action.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown conversation_token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "conversation_token": {
                    "description": "Bearer token returned once by the first talk_to_studio call.",
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 200
                  }
                },
                "required": [
                  "conversation_token"
                ]
              }
            }
          }
        }
      }
    },
    "/send_quote_message": {
      "post": {
        "operationId": "send_quote_message",
        "summary": "Send quote message",
        "description": "Reply in the live quote thread after submission. Staff are notified like a customer reply.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown conversation_token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "conversation_token": {
                    "description": "Bearer token returned once by the first talk_to_studio call.",
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 200
                  },
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "attachments": {
                    "maxItems": 5,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 2000,
                      "format": "uri"
                    }
                  }
                },
                "required": [
                  "conversation_token",
                  "message"
                ]
              }
            }
          }
        }
      }
    },
    "/check_spec": {
      "post": {
        "operationId": "check_spec",
        "summary": "Check a spec",
        "description": "Deterministic production check against our rules. Returns feasible plus blocking issues and warnings with fixes.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown conversation_token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string"
                        },
                        "retry_after_seconds": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "product": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "size": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "stock": {
                    "type": "string",
                    "maxLength": 300
                  },
                  "caliper_pt": {
                    "description": "Caliper in points (pt).",
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 400
                  },
                  "caliper_gsm": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 5000
                  },
                  "print_method": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "finishes": {
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    }
                  },
                  "edges": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "corners": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "square",
                          "rounded",
                          "custom"
                        ]
                      },
                      {
                        "type": "string",
                        "maxLength": 100
                      }
                    ]
                  },
                  "shape": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "sides": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "plies": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 4
                  },
                  "extras": {
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}