{
  "openapi": "3.0.3",
  "info": {
    "title": "ASAP Living API",
    "description": "REST API for ASAP Living, a furnished apartment rental service in Berlin. Provides access to apartment listings, rental applications, and contact messaging. All apartments are furnished, all-inclusive (rent + utilities + internet), and available for stays of 6-24 months.",
    "version": "1.0.0",
    "contact": {
      "name": "ASAP Living",
      "url": "https://www.asapliving.de/contact",
      "email": "info@asapliving.de"
    }
  },
  "servers": [
    {
      "url": "https://www.asapliving.de",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/listings": {
      "get": {
        "operationId": "getListings",
        "summary": "Get all available apartments",
        "description": "Returns all apartments currently available for rent. Results are cached server-side for 60 seconds. Only apartments marked for display are included, sorted by availability date (ascending). Sensitive fields (tenant data, financials) are stripped server-side.",
        "responses": {
          "200": {
            "description": "A list of available apartments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingsResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/apply": {
      "post": {
        "operationId": "submitApplication",
        "summary": "Submit a rental application",
        "description": "Creates a new rental application. The applicant can optionally link the application to a specific apartment by providing the apartment's record ID in the 'Wohnung' field. If no apartment is specified, ASAP Living will match the applicant to suitable listings.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplicationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Application created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordCreated"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/contact": {
      "post": {
        "operationId": "sendContactMessage",
        "summary": "Send a contact message",
        "description": "Sends a general contact message to ASAP Living. All three fields (Name, Email, Message) are required.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message sent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordCreated"
                }
              }
            }
          },
          "400": {
            "description": "Missing required fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Name, Email and Message are required"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ListingsResponse": {
        "type": "object",
        "properties": {
          "records": {
            "type": "array",
            "description": "Array of apartment records",
            "items": {
              "$ref": "#/components/schemas/ListingRecord"
            }
          }
        },
        "required": ["records"]
      },
      "ListingRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Airtable record ID (e.g., recXXXXXXXXXXXXXX). Use this to link applications to specific apartments.",
            "example": "recABC123def456gh"
          },
          "fields": {
            "$ref": "#/components/schemas/ListingFields"
          }
        },
        "required": ["id", "fields"]
      },
      "ListingFields": {
        "type": "object",
        "description": "Apartment data fields. Field names use German naming conventions from the underlying Airtable database.",
        "properties": {
          "Website Titel": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Apartment title. Array with one element; use the first entry.",
            "example": ["Bright 2BR in Kreuzberg"]
          },
          "Website Untertitel": {
            "type": "string",
            "description": "Subtitle displayed on the website card.",
            "example": "Furnished \u2022 All-inclusive"
          },
          "Website Kosten": {
            "type": "string",
            "description": "Formatted cost string for display.",
            "example": "1.850 EUR"
          },
          "Website Verf\u00fcgbarkeit": {
            "type": "string",
            "description": "Human-readable availability status.",
            "example": "Available Now"
          },
          "Adresse": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Full street address.",
            "example": ["Bergmannstr. 15, 10961 Berlin"]
          },
          "Stadtteil": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Berlin neighborhood.",
            "example": ["Kreuzberg"]
          },
          "Stadtteil2": {
            "type": "string",
            "description": "Sub-neighborhood or local area name.",
            "example": "Bergmannkiez"
          },
          "Schlafzimmer": {
            "type": "number",
            "description": "Number of bedrooms.",
            "example": 2
          },
          "WFL": {
            "type": "number",
            "description": "Living area in square meters.",
            "example": 68
          },
          "Gesamt SOLL": {
            "type": "number",
            "description": "Monthly all-inclusive rent in EUR.",
            "example": 1850
          },
          "verf\u00fcgbarkeit": {
            "type": "string",
            "format": "date",
            "description": "Availability date in ISO format.",
            "example": "2026-04-01"
          },
          "Art": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Apartment type.",
            "example": ["2-Zimmer-Wohnung"]
          },
          "Titelbild": {
            "type": "array",
            "description": "Cover image. Resized to 800px width via the image proxy.",
            "items": {
              "$ref": "#/components/schemas/Attachment"
            }
          },
          "Bilder Vermarktung": {
            "type": "array",
            "description": "Gallery images at full resolution.",
            "items": {
              "$ref": "#/components/schemas/Attachment"
            }
          },
          "Latitude": {
            "type": "number",
            "format": "double",
            "description": "GPS latitude.",
            "example": 52.4891
          },
          "Longitude": {
            "type": "number",
            "format": "double",
            "description": "GPS longitude.",
            "example": 13.3884
          }
        }
      },
      "Attachment": {
        "type": "object",
        "description": "An image attachment with URL and dimensions.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Attachment ID.",
            "example": "attXXXXXXXXXXXXXX"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Image URL. Titelbild images are served via /api/img proxy; Bilder Vermarktung images are direct CDN URLs."
          },
          "width": {
            "type": "integer",
            "description": "Image width in pixels.",
            "example": 800
          },
          "height": {
            "type": "integer",
            "description": "Image height in pixels.",
            "example": 533
          }
        }
      },
      "ApplicationRequest": {
        "type": "object",
        "properties": {
          "fields": {
            "type": "object",
            "description": "Application fields.",
            "properties": {
              "Vorname": {
                "type": "string",
                "description": "First name of the applicant.",
                "example": "John"
              },
              "Nachname": {
                "type": "string",
                "description": "Last name of the applicant.",
                "example": "Doe"
              },
              "Email": {
                "type": "string",
                "format": "email",
                "description": "Email address.",
                "example": "john@example.com"
              },
              "Phone": {
                "type": "string",
                "description": "Phone number.",
                "example": "+49 170 1234567"
              },
              "Move-in Date": {
                "type": "string",
                "format": "date",
                "description": "Desired move-in date (YYYY-MM-DD).",
                "example": "2026-05-01"
              },
              "Renting Period": {
                "type": "string",
                "description": "Desired lease duration.",
                "example": "12 months"
              },
              "Number of Tenants": {
                "type": "string",
                "description": "Number of people moving in.",
                "example": "2"
              },
              "Budget": {
                "type": "string",
                "description": "Monthly budget range in EUR.",
                "example": "2000-2500"
              },
              "Notes": {
                "type": "string",
                "description": "Additional notes or preferences.",
                "example": "Looking for 2BR in Kreuzberg"
              },
              "Wohnung": {
                "type": "string",
                "description": "Record ID of a specific apartment from /api/listings. Optional -- links the application to that apartment.",
                "example": "recABC123def456gh"
              }
            }
          }
        },
        "required": ["fields"]
      },
      "ContactRequest": {
        "type": "object",
        "properties": {
          "fields": {
            "type": "object",
            "description": "Contact message fields. All three are required.",
            "properties": {
              "Name": {
                "type": "string",
                "description": "Full name of the sender.",
                "example": "John Doe"
              },
              "Email": {
                "type": "string",
                "format": "email",
                "description": "Email address.",
                "example": "john@example.com"
              },
              "Message": {
                "type": "string",
                "description": "Message content.",
                "example": "I have a question about your apartments in Mitte."
              }
            },
            "required": ["Name", "Email", "Message"]
          }
        },
        "required": ["fields"]
      },
      "RecordCreated": {
        "type": "object",
        "description": "Returned when a record is successfully created.",
        "properties": {
          "id": {
            "type": "string",
            "description": "The Airtable record ID of the created record.",
            "example": "recABC123def456gh"
          }
        },
        "required": ["id"]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message describing what went wrong.",
            "example": "Internal server error"
          }
        }
      }
    }
  }
}
