{
  "openapi": "3.1.0",
  "info": {
    "title": "Ten Twelve Design Group | Public API",
    "version": "1.0.0",
    "description": "Public API of Ten Twelve Design Group Inc., a luxury design-build firm serving Miami and The Hamptons. No authentication required. Versioning: the API version lives in the URL path (/api/v1/). Deprecation policy: a deprecated version keeps working for at least 12 months and announces removal via Deprecation and Sunset response headers (RFC 8594). Rate limits are advertised on every response via RFC RateLimit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) plus Retry-After on 429.",
    "contact": {
      "email": "info@ten12group.com",
      "url": "https://ten12group.com/contact/"
    }
  },
  "servers": [
    {
      "url": "https://ten12group.com"
    }
  ],
  "paths": {
    "/api/v1/contact": {
      "post": {
        "operationId": "submitProjectInquiry",
        "summary": "Submit a project inquiry",
        "description": "Delivers a qualified inquiry to the studio inbox. No authentication required. Rate limit: 5 submissions per 15 minutes per client IP (RateLimit headers on every response).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Inquiry"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/Inquiry"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Inquiry delivered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Origin not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Inbox not connected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects": {
      "get": {
        "operationId": "listProjects",
        "summary": "List portfolio projects",
        "description": "Returns the public portfolio: title, location, scope, description and page URL per project.",
        "responses": {
          "200": {
            "description": "Project list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "projects"
                  ],
                  "properties": {
                    "projects": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "title",
                          "url"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "location": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "scope": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "url": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/services": {
      "get": {
        "operationId": "listServices",
        "summary": "List services",
        "description": "Returns the public service catalog: title, description, capabilities and page URL per service.",
        "responses": {
          "200": {
            "description": "Service list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "services"
                  ],
                  "properties": {
                    "services": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "title",
                          "url"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "capabilities": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/contact": {
      "post": {
        "deprecated": true,
        "operationId": "submitProjectInquiryLegacy",
        "summary": "Submit a project inquiry (unversioned alias of POST /api/v1/contact)",
        "description": "Kept for backward compatibility. Sends Deprecation and Sunset headers (RFC 8594). New integrations should use POST /api/v1/contact.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Inquiry"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/Inquiry"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Inquiry delivered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Origin not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Inbox not connected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Inquiry": {
        "type": "object",
        "required": [
          "name",
          "email",
          "message",
          "location",
          "budget",
          "phase"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "phone": {
            "type": "string",
            "maxLength": 32
          },
          "message": {
            "type": "string",
            "minLength": 10,
            "maxLength": 4000
          },
          "location": {
            "type": "string",
            "enum": [
              "miami",
              "hamptons",
              "other"
            ]
          },
          "budget": {
            "type": "string",
            "enum": [
              "under-1m",
              "1m-3m",
              "3m-10m",
              "over-10m",
              "undisclosed"
            ]
          },
          "phase": {
            "type": "string",
            "enum": [
              "pre-planning",
              "permitted",
              "unsure"
            ]
          }
        }
      },
      "Ok": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "ok",
          "error",
          "code",
          "hint"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string",
            "description": "Human-readable message"
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code"
          },
          "hint": {
            "type": "string",
            "description": "How to resolve the error"
          }
        }
      }
    }
  }
}
