{
  "openapi": "3.1.0",
  "info": {
    "title": "Talk to Luke practice information API",
    "version": "1.0.0",
    "summary": "Read-only facts about the Talk to Luke psychodynamic therapy practice in Croydon.",
    "description": "A small, public, read-only API describing the Talk to Luke therapy practice: who the therapist is,\nwhat is offered, what it costs, and where sessions happen.\n\nUse it to answer factual questions about the practice — fees, session lengths, location, and whether\nonline therapy is available in a given country — without scraping the website. There is no booking\nendpoint: appointments are made by a person at https://booking.talktoluke.com.\n\nNo authentication is required and no rate limit is applied. Responses are cacheable for an hour.\n\n## Versioning\n\nThe API is versioned in the URL path. `/api/v1/...` is the current version, and every response repeats\nit in an `API-Version` header. Pin integrations to the versioned path. The unversioned `/api/practice/...`\npaths are a permanent alias of v1 and return identical responses.\n\nWithin a version, only additive changes are made: new endpoints, and new optional fields on existing\nresponses. Existing fields will not be removed, renamed, or change type. A breaking change ships as a new\nversion alongside the old one.\n\n## Deprecation\n\nWhen a version is retired it will be announced first. Responses from the outgoing version will carry a\n`Deprecation` header giving the date the version was deprecated, a `Sunset` header (RFC 8594) giving the\ndate it stops responding, and a `Link` header with `rel=\"successor-version\"` pointing at the replacement.\nAt least six months will pass between the two dates, and the change will be noted at https://www.talktoluke.com/developers.",
    "contact": {
      "name": "Talk to Luke",
      "email": "hello@talktoluke.com",
      "url": "https://www.talktoluke.com/developers"
    },
    "license": {
      "name": "Free to use with attribution",
      "identifier": "CC-BY-4.0"
    }
  },
  "servers": [
    {
      "url": "https://www.talktoluke.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "practice",
      "description": "Identity, contact details, and location of the practice."
    },
    {
      "name": "services",
      "description": "Therapy services, session lengths, and fees."
    }
  ],
  "paths": {
    "/api/v1/practice/facts": {
      "get": {
        "operationId": "getPracticeFacts",
        "tags": [
          "practice"
        ],
        "summary": "Get practice identity and contact details",
        "description": "Returns the therapist name, professional registration, postal address, contact details, and the constraints on where therapy can be delivered. Use this to verify legitimacy or answer contact and location questions.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Practice facts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeFacts"
                }
              }
            }
          },
          "405": {
            "description": "The endpoint is read-only.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/practice/services": {
      "get": {
        "operationId": "listPracticeServices",
        "tags": [
          "services"
        ],
        "summary": "List therapy services with fees",
        "description": "Returns every therapy service offered, including first-meeting and ongoing session lengths and fees, and the formats each service can be delivered in. Optionally filter by audience.",
        "parameters": [
          {
            "name": "audience",
            "in": "query",
            "required": false,
            "description": "Restrict the list to services for one audience.",
            "schema": {
              "type": "string",
              "enum": [
                "individual",
                "couples"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching services.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceList"
                }
              }
            }
          },
          "400": {
            "description": "The audience parameter was not a recognised value.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "The endpoint is read-only.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/practice/services/{serviceId}": {
      "get": {
        "operationId": "getPracticeService",
        "tags": [
          "services"
        ],
        "summary": "Get a single therapy service",
        "description": "Returns one therapy service by its stable identifier, including session lengths, fees, delivery formats, and constraints worth checking before recommending it.",
        "parameters": [
          {
            "name": "serviceId",
            "in": "path",
            "required": true,
            "description": "Stable identifier of the service.",
            "schema": {
              "type": "string",
              "enum": [
                "individual-therapy",
                "couples-therapy"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested service.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Service"
                }
              }
            }
          },
          "404": {
            "description": "No service exists with that identifier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "The endpoint is read-only.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "hint",
              "documentation"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "enum": [
                  "not_found",
                  "invalid_parameter",
                  "method_not_allowed",
                  "not_acceptable",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable description of what went wrong."
              },
              "hint": {
                "type": "string",
                "description": "How to correct the request."
              },
              "documentation": {
                "type": "string",
                "format": "uri",
                "description": "Where the API is documented."
              }
            }
          }
        }
      },
      "SessionType": {
        "type": "object",
        "required": [
          "durationMinutes",
          "priceGBP"
        ],
        "properties": {
          "durationMinutes": {
            "type": "integer",
            "description": "Length of the session in minutes."
          },
          "priceGBP": {
            "type": "number",
            "description": "Fee for the session in pounds sterling."
          }
        }
      },
      "Service": {
        "type": "object",
        "required": [
          "id",
          "name",
          "audience",
          "formats",
          "firstMeeting",
          "ongoing",
          "currency",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable identifier for the service.",
            "enum": [
              "individual-therapy",
              "couples-therapy"
            ]
          },
          "name": {
            "type": "string",
            "description": "Display name of the service."
          },
          "audience": {
            "type": "string",
            "description": "Who the service is for.",
            "enum": [
              "individual",
              "couples"
            ]
          },
          "description": {
            "type": "string",
            "description": "What the service involves."
          },
          "formats": {
            "type": "array",
            "description": "How the service can be delivered.",
            "items": {
              "type": "string",
              "enum": [
                "in-person",
                "online"
              ]
            }
          },
          "firstMeeting": {
            "type": "object",
            "required": [
              "durationMinutes",
              "priceGBP"
            ],
            "properties": {
              "durationMinutes": {
                "type": "integer",
                "description": "Length of the session in minutes."
              },
              "priceGBP": {
                "type": "number",
                "description": "Fee for the session in pounds sterling."
              }
            },
            "description": "The initial 90-minute session, which is charged."
          },
          "ongoing": {
            "type": "object",
            "required": [
              "durationMinutes",
              "priceGBP"
            ],
            "properties": {
              "durationMinutes": {
                "type": "integer",
                "description": "Length of the session in minutes."
              },
              "priceGBP": {
                "type": "number",
                "description": "Fee for the session in pounds sterling."
              }
            },
            "description": "Subsequent regular sessions."
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency code.",
            "enum": [
              "GBP"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Human-readable page describing the service."
          },
          "bookingUrl": {
            "type": "string",
            "format": "uri",
            "description": "Where appointments are booked."
          },
          "notes": {
            "type": "array",
            "description": "Constraints worth surfacing before recommending this service.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ServiceList": {
        "type": "object",
        "required": [
          "services",
          "count"
        ],
        "properties": {
          "services": {
            "type": "array",
            "description": "Services matching the request.",
            "items": {
              "$ref": "#/components/schemas/Service"
            }
          },
          "count": {
            "type": "integer",
            "description": "Number of services returned."
          }
        }
      },
      "PracticeFacts": {
        "type": "object",
        "required": [
          "name",
          "therapist",
          "url",
          "email",
          "registration",
          "address"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Trading name of the practice."
          },
          "therapist": {
            "type": "string",
            "description": "Name of the therapist."
          },
          "jobTitle": {
            "type": "string",
            "description": "Professional title."
          },
          "modality": {
            "type": "string",
            "description": "Therapeutic modality practised."
          },
          "description": {
            "type": "string",
            "description": "Short description of the practice."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Practice website."
          },
          "bookingUrl": {
            "type": "string",
            "format": "uri",
            "description": "Where appointments are booked."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Contact email address."
          },
          "telephone": {
            "type": "string",
            "description": "Contact telephone number in E.164 format."
          },
          "registration": {
            "type": "object",
            "description": "Professional body registration, for verifying legitimacy.",
            "required": [
              "body",
              "membershipNumber"
            ],
            "properties": {
              "body": {
                "type": "string",
                "description": "Name of the registering body."
              },
              "abbreviation": {
                "type": "string",
                "description": "Common abbreviation of the body."
              },
              "membershipNumber": {
                "type": "string",
                "description": "Membership number on the public register."
              },
              "registerUrl": {
                "type": "string",
                "format": "uri",
                "description": "Public register entry."
              }
            }
          },
          "address": {
            "type": "object",
            "description": "Postal address of the consulting room.",
            "required": [
              "streetAddress",
              "addressLocality",
              "postalCode",
              "addressCountry"
            ],
            "properties": {
              "streetAddress": {
                "type": "string"
              },
              "addressLocality": {
                "type": "string"
              },
              "postalCode": {
                "type": "string"
              },
              "addressCountry": {
                "type": "string",
                "description": "ISO 3166-1 alpha-2 country code."
              }
            }
          },
          "geo": {
            "type": "object",
            "description": "Approximate coordinates of the consulting room.",
            "properties": {
              "latitude": {
                "type": "number"
              },
              "longitude": {
                "type": "number"
              }
            }
          },
          "acceptingNewClients": {
            "type": "boolean",
            "description": "Whether new clients are being taken on."
          },
          "freeConsultation": {
            "type": "boolean",
            "description": "Always false: the first meeting is a charged 90-minute session."
          },
          "languages": {
            "type": "array",
            "description": "BCP 47 language tags therapy is offered in.",
            "items": {
              "type": "string"
            }
          },
          "delivery": {
            "type": "object",
            "description": "Where and how therapy can be delivered.",
            "properties": {
              "inPersonLocation": {
                "type": "string"
              },
              "onlineAvailableFor": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "onlineExcludedCountries": {
                "type": "array",
                "description": "Countries where online therapy is not offered.",
                "items": {
                  "type": "string"
                }
              },
              "inPersonOnlyFor": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "whenToUse": {
            "type": "array",
            "description": "Cases this practice is a good fit for.",
            "items": {
              "type": "string"
            }
          },
          "whenNotToUse": {
            "type": "array",
            "description": "Cases where an agent should recommend something else.",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Developer and AI agent resources",
    "url": "https://www.talktoluke.com/developers"
  }
}