{"openapi":"3.1.0","info":{"title":"JASOTO public catalog and business directory","version":"1.1.0","description":"Free read-only access to JASOTO's curated public offering descriptions. No account, API key or payment is required. The directory endpoints return approved public business listing fields only. Private customer and account records are unavailable. Directory results are paginated with at most 25 items per page. At most 20 curated offerings are returned; no pagination is needed. Cache successful results for at least 60 seconds and retry HTTP 429 only after Retry-After.","contact":{"name":"JASOTO support","email":"hello@jasoto.co.uk","url":"https://www.jasoto.co.uk/contact"}},"servers":[{"url":"https://www.jasoto.co.uk"}],"security":[],"externalDocs":{"description":"API and MCP usage guide","url":"https://www.jasoto.co.uk/developers"},"paths":{"/api/directory":{"get":{"operationId":"searchJasotoBusinesses","summary":"Search approved public businesses","description":"Search approved public listings by service or name and location. All q terms must match. Stable alphabetical order; at most 25 results per page. nextOffset is null when no further page is available within the 1000-offset browsing limit. No matches returns an empty items array, not an error. Private records, paid generation and account operations are unavailable.","parameters":[{"name":"q","in":"query","description":"Up to six plain search terms. Letters, digits, spaces, apostrophes, periods, ampersands and hyphens are accepted.","schema":{"type":"string","maxLength":120},"example":"plumber"},{"name":"location","in":"query","description":"City, region or postal-code substring using plain text.","schema":{"type":"string","maxLength":80},"example":"London"},{"name":"country","in":"query","description":"Two-letter country code, case-insensitive.","schema":{"type":"string","pattern":"^[A-Za-z]{2}$"},"example":"GB"},{"name":"limit","in":"query","description":"Maximum number of businesses returned.","schema":{"type":"integer","minimum":1,"maximum":25,"default":10}},{"name":"offset","in":"query","description":"Pagination offset; use nextOffset from the previous response.","schema":{"type":"integer","minimum":0,"maximum":1000,"default":0}}],"responses":{"200":{"description":"Matching businesses and pagination","content":{"application/json":{"schema":{"type":"object","required":["items","limit","offset","nextOffset"],"properties":{"items":{"type":"array","maxItems":25,"items":{"$ref":"#/components/schemas/PublicBusiness"}},"limit":{"type":"integer","minimum":1,"maximum":25},"offset":{"type":"integer","minimum":0,"maximum":1000},"nextOffset":{"type":["integer","null"],"minimum":0,"maximum":1000}}}}}},"400":{"description":"Structured error with code, message and resolution hint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured error with code, message and resolution hint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Structured error with code, message and resolution hint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","example":30}}}}}}},"/api/directory/{identifier}":{"get":{"operationId":"getJasotoBusiness","summary":"Read an approved public business","description":"Read a public business by slug or UUID returned by searchJasotoBusinesses. quoteUrl links to the existing website enquiry flow; it does not submit an enquiry, charge money or book work.","parameters":[{"name":"identifier","in":"path","required":true,"description":"Public business slug or UUID.","schema":{"type":"string","maxLength":200,"pattern":"^[A-Za-z0-9][A-Za-z0-9-]*$"}}],"responses":{"200":{"description":"Public business profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBusiness"}}}},"400":{"description":"Structured error with code, message and resolution hint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Structured error with code, message and resolution hint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Structured error with code, message and resolution hint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Structured error with code, message and resolution hint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/offerings":{"get":{"operationId":"listJasotoOfferings","summary":"List or search public offerings","description":"Read every curated public offering, or search name, description, audience and features. All whitespace-separated query terms must match. An unmatched query returns an empty list with HTTP 200.","parameters":[{"name":"q","in":"query","required":false,"description":"Optional search terms; at most 200 characters.","schema":{"type":"string","maxLength":200},"example":"language"}],"responses":{"200":{"description":"Matching public offerings","content":{"application/json":{"schema":{"type":"object","required":["items","total"],"properties":{"items":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/Offering"}},"total":{"type":"integer","minimum":0,"maximum":20}}}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Unsupported method; use GET or HEAD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/offerings/{slug}":{"get":{"operationId":"getJasotoOffering","summary":"Read one public offering","description":"Read the full curated description, access conditions, features, steps, FAQ and canonical guide links for a slug returned by the catalog.","parameters":[{"name":"slug","in":"path","required":true,"description":"An exact offering slug returned by GET /api/offerings.","schema":{"type":"string"},"example":"free-business-listing"}],"responses":{"200":{"description":"The public offering","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Offering"}}}},"404":{"description":"No offering matches this slug","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"Unsupported method; use GET or HEAD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Offering":{"type":"object","additionalProperties":false,"required":["slug","name","description","audience","href","action","access","features","steps","questions","url","guideUrl","markdownUrl"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"audience":{"type":"string"},"href":{"type":"string"},"action":{"type":"string"},"access":{"type":"string"},"url":{"type":"string","format":"uri"},"guideUrl":{"type":"string","format":"uri"},"markdownUrl":{"type":"string","format":"uri"},"features":{"type":"array","items":{"type":"object","required":["title","text"],"properties":{"title":{"type":"string"},"text":{"type":"string"},"link":{"type":"object","required":["href","label"],"properties":{"href":{"type":"string"},"label":{"type":"string"}}}}}},"steps":{"type":"array","items":{"type":"string"}},"questions":{"type":"array","items":{"type":"object","required":["question","answer"],"properties":{"question":{"type":"string"},"answer":{"type":"string"}}}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","resolution"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"resolution":{"type":"string"}}}}},"PublicBusiness":{"type":"object","additionalProperties":false,"required":["id","slug","name","service","category","description","location","profileUrl","markdownUrl","quoteUrl"],"properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"service":{"type":"string"},"category":{"type":"string"},"description":{"type":"string","maxLength":3000},"location":{"type":"object","additionalProperties":false,"required":["city","region","postalCode","country"],"properties":{"city":{"type":"string"},"region":{"type":"string"},"postalCode":{"type":"string"},"country":{"type":"string"}}},"profileUrl":{"type":"string","format":"uri"},"markdownUrl":{"type":"string","format":"uri"},"quoteUrl":{"type":"string","format":"uri"}}}}}}