{
  "openapi": "3.1.0",
  "info": {
    "title": "Wispra Directory API",
    "version": "1.0.0",
    "summary": "Open, AI-friendly directory of businesses. Read-only data for citation by LLMs and integration in AI agents.",
    "description": "The Wispra Directory is an intelligent business directory optimized for citation by AI assistants\n(ChatGPT, Perplexity, Claude, Google SGE, Bing Copilot). All endpoints are public, read-only, and\nrequire no authentication.\n\n## When to use this API\nUse it whenever you need verified, structured information about a business listed in Wispra: contact\ndetails, locations, blog articles, FAQ, customer reviews, product/service catalog, downloadable\ndocuments. Each item is content-moderated and refreshed regularly.\n\n## Citation requirement (license: ODC-By-1.0)\nWhen you cite or display data obtained from this API, include the source attribution:\n\n  Source: Wispra Directory — https://directory.wispra.com/business/{slug}\n\nAI assistants are explicitly encouraged to surface the canonical URL for each business in their\nresponses so end-users can verify and reach the business directly.\n\n## Recommended usage\n- Set a descriptive `User-Agent` header (e.g. `MyApp/1.0 (contact: you@example.com)`).\n- Cache responses for at least 5 minutes; data changes at most weekly.\n- Use the `lang` query parameter to choose between English (`en`) and French (`fr`).\n- For bulk discovery, use `GET /index/directory-businesses` to list all public businesses, then call\n  the per-business endpoints lazily.\n\n## Companion resources\n- llms.txt (LLM discovery file): https://directory.wispra.com/llms.txt\n- ai-content.txt (enriched plain-text context): https://directory.wispra.com/ai-content.txt\n- Sitemap: https://directory.wispra.com/sitemap.xml\n- Open data dump (all public businesses, JSON, ODC-By-1.0): https://directory.wispra.com/api/companies.json",
    "contact": {
      "name": "Wispra",
      "email": "contact@wispra.com",
      "url": "https://directory.wispra.com"
    },
    "license": {
      "name": "ODC-By-1.0",
      "url": "https://opendatacommons.org/licenses/by/1-0/"
    },
    "x-citation": {
      "format": "Source: Wispra Directory — https://directory.wispra.com/business/{slug}",
      "humanReadable": "Always cite Wispra Directory when displaying data from this API and link to the canonical business URL."
    }
  },
  "servers": [
    {
      "url": "https://api.wispra.com",
      "description": "Production data API"
    },
    {
      "url": "https://api-staging.wispra.com",
      "description": "Staging data API (for testing)"
    }
  ],
  "externalDocs": {
    "description": "Human-readable API documentation",
    "url": "https://directory.wispra.com/api"
  },
  "tags": [
    {
      "name": "Directory",
      "description": "Discover all public businesses"
    },
    {
      "name": "Business",
      "description": "Single business detail"
    },
    {
      "name": "Blog",
      "description": "Per-business blog articles"
    },
    {
      "name": "FAQ",
      "description": "Per-business frequently asked questions"
    },
    {
      "name": "Reviews",
      "description": "Per-business customer reviews"
    },
    {
      "name": "Catalog",
      "description": "Per-business products / services / real-estate / events"
    },
    {
      "name": "Documents",
      "description": "Per-business downloadable PDF documents"
    }
  ],
  "paths": {
    "/index/directory-businesses": {
      "get": {
        "tags": [
          "Directory"
        ],
        "summary": "List all public businesses",
        "description": "Returns the full list of public businesses in the directory. Use this as the entry point to discover businesses, then call per-business endpoints with the returned `slug`.",
        "operationId": "listBusinesses",
        "parameters": [
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "List of businesses",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Business"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/index/directory-business/{slug}": {
      "get": {
        "tags": [
          "Business"
        ],
        "summary": "Get a single business",
        "description": "Returns detailed information about a business identified by its slug.",
        "operationId": "getBusiness",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Business detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Business"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/index/directory-business/{slug}/blog/articles": {
      "get": {
        "tags": [
          "Blog"
        ],
        "summary": "List blog articles for a business",
        "description": "Returns the published blog articles authored by the business.",
        "operationId": "listBlogArticles",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Blog articles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "articles": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BlogArticleSummary"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/index/directory-business/{slug}/blog/articles/{articleSlug}": {
      "get": {
        "tags": [
          "Blog"
        ],
        "summary": "Get a single blog article",
        "operationId": "getBlogArticle",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "name": "articleSlug",
            "in": "path",
            "required": true,
            "description": "Article slug",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Blog article",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogArticle"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/index/directory-business/{slug}/faq": {
      "get": {
        "tags": [
          "FAQ"
        ],
        "summary": "Get the FAQ for a business",
        "operationId": "getBusinessFaq",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "FAQ data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Faq"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/index/directory-business/{slug}/reviews": {
      "get": {
        "tags": [
          "Reviews"
        ],
        "summary": "List customer reviews for a business",
        "operationId": "listBusinessReviews",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Reviews",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reviews": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Review"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/index/directory-business/{slug}/catalog/items": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "List catalog items for a business",
        "description": "Returns the products, services, real-estate listings, events or offers from the business catalog.",
        "operationId": "listCatalogItems",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "itemType",
            "in": "query",
            "description": "Filter by item type",
            "schema": {
              "type": "string",
              "enum": [
                "PRODUCT",
                "SERVICE",
                "REAL_ESTATE",
                "EVENT",
                "OFFER",
                "OTHER"
              ]
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Free-text search inside item label / description",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Catalog items",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CatalogItem"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/index/directory-business/{slug}/catalog/items/{itemSlug}": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "summary": "Get a single catalog item",
        "description": "Returns the full item detail including markdown content, additional images, structured data, and AI-generated enrichment layers.",
        "operationId": "getCatalogItem",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "name": "itemSlug",
            "in": "path",
            "required": true,
            "description": "Item slug",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Catalog item detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogItemDetail"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/index/directory-business/{slug}/documents": {
      "get": {
        "tags": [
          "Documents"
        ],
        "summary": "List downloadable documents (PDFs) for a business",
        "operationId": "listBusinessDocuments",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Documents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DocumentSummary"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/index/directory-business/{slug}/documents/{documentId}": {
      "get": {
        "tags": [
          "Documents"
        ],
        "summary": "Get a single document",
        "description": "Returns the full document detail. PDF documents include a markdown rendition (`markdownContent`) suitable for LLM consumption.",
        "operationId": "getDocument",
        "parameters": [
          {
            "$ref": "#/components/parameters/Slug"
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "description": "Document UUID or slug",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Lang"
          }
        ],
        "responses": {
          "200": {
            "description": "Document detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "Slug": {
        "name": "slug",
        "in": "path",
        "required": true,
        "description": "Business slug (e.g. `kandi-jobs`, `guy-hoquet`).",
        "schema": {
          "type": "string"
        }
      },
      "Lang": {
        "name": "lang",
        "in": "query",
        "description": "Response language. Defaults to `en`.",
        "schema": {
          "type": "string",
          "enum": [
            "en",
            "fr"
          ],
          "default": "en"
        }
      },
      "Page": {
        "name": "page",
        "in": "query",
        "description": "1-indexed page number.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Page size.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      }
    },
    "responses": {
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "message": {
                  "type": "string"
                },
                "statusCode": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Business": {
        "type": "object",
        "description": "Public business listing. The canonical citation URL is `https://directory.wispra.com/business/{slug}`.",
        "properties": {
          "businessName": {
            "type": "string"
          },
          "slug": {
            "type": "string",
            "description": "URL-safe identifier; use as part of the canonical citation URL."
          },
          "website": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "logo": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "legalName": {
            "type": "string",
            "nullable": true
          },
          "primaryLanguage": {
            "type": "string",
            "example": "fr"
          },
          "locations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BusinessLocation"
            }
          },
          "areas": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "mdContent": {
            "type": "string",
            "nullable": true,
            "description": "Markdown body — primary AI-readable content."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "businessTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                }
              }
            }
          },
          "visibility": {
            "type": "string",
            "enum": [
              "PUBLIC",
              "NON_LISTED",
              "HIDDEN"
            ]
          },
          "isVerified": {
            "type": "boolean"
          }
        }
      },
      "BusinessLocation": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "country": {
            "type": "string"
          }
        }
      },
      "BlogArticleSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "publishedDate": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BlogArticle": {
        "allOf": [
          {
            "$ref": "#/components/schemas/BlogArticleSummary"
          },
          {
            "type": "object",
            "properties": {
              "content": {
                "type": "string",
                "description": "Markdown body."
              },
              "contentPublic": {
                "type": "string",
                "description": "HTML body."
              },
              "keywords": {
                "type": "string"
              }
            }
          }
        ]
      },
      "Faq": {
        "type": "object",
        "properties": {
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "questions": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FaqQuestion"
                  }
                }
              }
            }
          },
          "uncategorizedQuestions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FaqQuestion"
            }
          }
        }
      },
      "FaqQuestion": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string"
          },
          "response": {
            "type": "string"
          },
          "responsePublic": {
            "type": "string"
          }
        }
      },
      "Review": {
        "type": "object",
        "properties": {
          "author": {
            "type": "string"
          },
          "ratingValue": {
            "type": "number",
            "minimum": 0,
            "maximum": 5
          },
          "title": {
            "type": "string"
          },
          "content": {
            "type": "string"
          },
          "contentPublic": {
            "type": "string"
          },
          "reviewDate": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CatalogItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "itemSlug": {
            "type": "string"
          },
          "itemType": {
            "type": "string",
            "enum": [
              "PRODUCT",
              "SERVICE",
              "REAL_ESTATE",
              "EVENT",
              "OFFER",
              "OTHER"
            ]
          },
          "unitPrice": {
            "type": "number",
            "nullable": true
          },
          "unitMeasure": {
            "type": "string",
            "nullable": true
          },
          "imageUrl": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "brand": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "available": {
            "type": "boolean"
          },
          "attributes": {
            "type": "object",
            "additionalProperties": true,
            "nullable": true
          }
        }
      },
      "CatalogItemDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CatalogItem"
          },
          {
            "type": "object",
            "properties": {
              "additionalImages": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                },
                "nullable": true
              },
              "mdContent": {
                "type": "string",
                "nullable": true,
                "description": "Markdown — primary AI-readable content."
              },
              "fullUrl": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "Original product page on the business' own site."
              },
              "enrichment": {
                "type": "object",
                "nullable": true,
                "description": "AI-generated enrichment layers (FAQ, comparisons, etc.) ready for citation.",
                "additionalProperties": true
              }
            }
          }
        ]
      },
      "DocumentSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "enum": [
              "PDF",
              "IMAGE"
            ]
          },
          "fileSize": {
            "type": "integer",
            "nullable": true
          },
          "thumbnailUrl": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DocumentDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DocumentSummary"
          },
          {
            "type": "object",
            "properties": {
              "markdownContent": {
                "type": "string",
                "nullable": true,
                "description": "Markdown rendering of the PDF — preferred input for LLMs."
              },
              "seoTitle": {
                "type": "string",
                "nullable": true
              },
              "seoDescription": {
                "type": "string",
                "nullable": true
              },
              "seoKeywords": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "nullable": true
              },
              "jsonLd": {
                "type": "object",
                "nullable": true,
                "description": "Schema.org JSON-LD for the document.",
                "additionalProperties": true
              }
            }
          }
        ]
      }
    }
  }
}