{
  "openapi": "3.1.0",
  "info": {
    "title": "The Levant House Content API",
    "summary": "Read-only studio content for The Levant House.",
    "description": "Public, read-only JSON for The Levant House, a Croydon interior design studio. It returns published projects, journal articles, and enquiry notes already on the website. It is not a booking or commerce API. People still enquire through the HTML contact form or email.",
    "version": "1.0.0",
    "contact": {
      "name": "The Levant House",
      "email": "hello@thelevanthouse.com",
      "url": "https://www.thelevanthouse.com/contact"
    },
    "license": {
      "name": "All rights reserved. Studio content, not an open-source SDK"
    }
  },
  "servers": [
    {
      "url": "https://www.thelevanthouse.com",
      "description": "Production site for The Levant House"
    }
  ],
  "tags": [
    {
      "name": "Projects",
      "description": "Residential interiors published in the portfolio."
    },
    {
      "name": "Journal",
      "description": "Essays and practical notes from the studio."
    },
    {
      "name": "Studio",
      "description": "Identity, NAP, fees, and how a person should enquire."
    }
  ],
  "paths": {
    "/api/v1/projects": {
      "get": {
        "operationId": "listProjects",
        "tags": [
          "Projects"
        ],
        "summary": "List published portfolio projects",
        "description": "Returns every published project, or only featured projects when the featured query flag is set. Use this to choose a slug before calling getProject.",
        "parameters": [
          {
            "name": "featured",
            "in": "query",
            "required": false,
            "description": "When true, only featured projects. When false, only projects that are not featured. Omit to return all projects.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list of project summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectListResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request used an invalid parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "The HTTP method is not allowed on this resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{slug}": {
      "get": {
        "operationId": "getProject",
        "tags": [
          "Projects"
        ],
        "summary": "Get one portfolio project",
        "description": "Returns one project by its URL slug, including the narrative body and image URLs.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Project slug from listProjects, for example macleane-house.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A single project.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request used an invalid parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "The requested record does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "The HTTP method is not allowed on this resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/journal": {
      "get": {
        "operationId": "listJournalArticles",
        "tags": [
          "Journal"
        ],
        "summary": "List published journal articles",
        "description": "Returns published journal articles, newest first. Use a returned slug with getJournalArticle.",
        "responses": {
          "200": {
            "description": "A list of journal article summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalListResponse"
                }
              }
            }
          },
          "405": {
            "description": "The HTTP method is not allowed on this resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/journal/{slug}": {
      "get": {
        "operationId": "getJournalArticle",
        "tags": [
          "Journal"
        ],
        "summary": "Get one journal article",
        "description": "Returns one journal article by slug, including the full body text.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Article slug from listJournalArticles, for example victorian-terrace-living-room.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A single journal article.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request used an invalid parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "The requested record does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "The HTTP method is not allowed on this resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/studio": {
      "get": {
        "operationId": "getStudio",
        "tags": [
          "Studio"
        ],
        "summary": "Get studio identity and enquiry notes",
        "description": "Returns the studio name, designer, contact details, service areas, published fees, and how a person should enquire. There is no POST enquiry endpoint. People still use the HTML form or email.",
        "responses": {
          "200": {
            "description": "Studio and enquiry metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudioResponse"
                }
              }
            }
          },
          "405": {
            "description": "The HTTP method is not allowed on this resource.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "code",
              "message",
              "hint"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "examples": [
                  "not_found",
                  "invalid_parameter",
                  "method_not_allowed"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation of what went wrong."
              },
              "hint": {
                "type": "string",
                "description": "What to try next so a client can recover without scraping HTML."
              }
            }
          }
        }
      },
      "ProjectSummary": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "slug",
          "title",
          "location",
          "propertyType",
          "scope",
          "duration",
          "category",
          "featured",
          "heroImage",
          "url"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "title": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "propertyType": {
            "type": "string"
          },
          "scope": {
            "type": "string"
          },
          "duration": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "featured": {
            "type": "boolean"
          },
          "heroImage": {
            "type": "string",
            "format": "uri"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "ProjectDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "slug",
          "title",
          "location",
          "propertyType",
          "scope",
          "duration",
          "category",
          "featured",
          "heroImage",
          "url",
          "images",
          "body"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "title": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "propertyType": {
            "type": "string"
          },
          "scope": {
            "type": "string"
          },
          "duration": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "featured": {
            "type": "boolean"
          },
          "heroImage": {
            "type": "string",
            "format": "uri"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "images": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "body": {
            "type": "string",
            "description": "Project narrative as stored in the studio content files."
          },
          "testimonial": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "quote",
              "client"
            ],
            "properties": {
              "quote": {
                "type": "string"
              },
              "client": {
                "type": "string"
              }
            }
          }
        }
      },
      "JournalSummary": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "slug",
          "title",
          "date",
          "excerpt",
          "category",
          "coverImage",
          "url"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "title": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "excerpt": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "coverImage": {
            "type": "string",
            "format": "uri"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "JournalDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "slug",
          "title",
          "date",
          "excerpt",
          "category",
          "coverImage",
          "url",
          "body"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "title": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "excerpt": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "coverImage": {
            "type": "string",
            "format": "uri"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "body": {
            "type": "string",
            "description": "Journal article body as stored in the studio content files."
          }
        }
      },
      "CollectionMeta": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "count",
          "documentation",
          "openapi"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 0
          },
          "documentation": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "ProjectListResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProjectSummary"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/CollectionMeta"
          }
        }
      },
      "ProjectDetailResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ProjectDetail"
          }
        }
      },
      "JournalListResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalSummary"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/CollectionMeta"
          }
        }
      },
      "JournalDetailResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/JournalDetail"
          }
        }
      },
      "StudioResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/StudioRecord"
          }
        }
      },
      "StudioRecord": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "alternateName",
          "designer",
          "tagline",
          "description",
          "email",
          "telephone",
          "telephoneE164",
          "url",
          "locale",
          "address",
          "areas",
          "sameAs",
          "enquiry",
          "fees"
        ],
        "properties": {
          "name": {
            "type": "string",
            "examples": [
              "The Levant House"
            ]
          },
          "alternateName": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "designer": {
            "type": "string"
          },
          "tagline": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "telephone": {
            "type": "string"
          },
          "telephoneE164": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "locale": {
            "type": "string"
          },
          "address": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "addressLocality",
              "addressRegion",
              "postalCode",
              "addressCountry"
            ],
            "properties": {
              "addressLocality": {
                "type": "string"
              },
              "addressRegion": {
                "type": "string"
              },
              "postalCode": {
                "type": "string"
              },
              "addressCountry": {
                "type": "string"
              }
            }
          },
          "areas": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sameAs": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "enquiry": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "humanFormUrl",
              "email",
              "discoveryCall",
              "notes",
              "formSubmit"
            ],
            "properties": {
              "humanFormUrl": {
                "type": "string",
                "format": "uri"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "discoveryCall": {
                "type": "string"
              },
              "notes": {
                "type": "string"
              },
              "formSubmit": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "fees": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "service",
                "price"
              ],
              "properties": {
                "service": {
                  "type": "string"
                },
                "price": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}
