---
title: "Developers and AI agents | SISO Builders"
description: "SISO Builders' open API, MCP servers, sandbox and discovery files: everything an agent or integration needs, no keys required."
canonical: https://sisobuilders.com/developers
---

# Developers and AI agents

An open API, two MCP servers, WebMCP tools and markdown for every page. No keys, no sign-up.

## Overview

SISO Builders is a residential remodeling contractor in South Florida. This page is for developers and AI agents that want to read the site programmatically or send an estimate request on a homeowner's behalf. Everything here is open: no API keys, no OAuth, no sign-up. See [auth.md](https://sisobuilders.com/auth.md) for the one-paragraph auth story.

Three surfaces, one data set: a JSON API under [/api/v1](https://sisobuilders.com/api/v1) described by [openapi.json](https://sisobuilders.com/openapi.json); two MCP servers ([/mcp](https://sisobuilders.com/mcp) for actions, [/mcp/docs](https://sisobuilders.com/mcp/docs) for reading); and markdown twins of every page (append `.md` or send `Accept: text/markdown`).

## Quickstart

List projects, then validate an estimate request in the sandbox. Nothing below needs a credential.

```bash
curl -s https://sisobuilders.com/api/v1/projects?category=kitchen

curl -s -X POST https://sisobuilders.com/api/v1/sandbox/inquiries \
  -H 'Content-Type: application/json' \
  -d '{"name":"Ann Example","email":"ann@example.com","message":"Kitchen remodel in Davie, starting in the spring"}'
```

## Endpoints

Base URL `https://sisobuilders.com/api/v1`. All responses are JSON; every error is an RFC 9457 problem (see [Errors](#errors)).

| Method | Path | What it returns |
| --- | --- | --- |
| GET | /api/v1 | The index: spec, docs, sandbox, MCP servers, endpoints |
| GET | /api/v1/projects | Published projects, cursor-paginated; `?category=` filters by room type |
| GET | /api/v1/projects/{slug} | One project with all its photos and videos |
| GET | /api/v1/services | The remodeling services offered |
| GET | /api/v1/business | Contact details, service area, hours, license, process, FAQ, pricing model |
| POST | /api/v1/inquiries | Submit a free estimate request (creates a real lead) |
| POST | /api/v1/sandbox/inquiries | Same validation and response, nothing stored or sent |

## Inquiries and the sandbox

An inquiry is a homeowner asking for a free on-site estimate. `POST /api/v1/inquiries` creates a real record in the owner's inbox and sends two emails (a notification to the team, a confirmation to the homeowner), so confirm the details with the homeowner before calling it.

The sandbox at `POST /api/v1/sandbox/inquiries` runs the exact same validation and returns the exact same shapes, with `data.sandbox: true` and `data.wouldSend` echoing the sanitized lead. Use it while building; switch the path when you ship. The MCP tool `request_estimate` has the same switch as `dry_run: true`.

- `name` (2–100 characters), `email`, `message` (10–2000 characters: the room, the city, roughly when) are required; `phone` and `sourcePage` are optional.
- A 201 means the request was received; 400 lists the invalid fields in `errors[]`; 429 means the limit of 3 real inquiries per 10 minutes per IP was reached.
- The endpoint is not idempotent. Retry only when no response arrived; a duplicate creates a second inquiry.

## Errors

Every error, including unknown paths under `/api`, is `application/problem+json` with a stable `code`:

```json
{
  "type": "https://sisobuilders.com/developers#error-validation-failed",
  "title": "Validation failed",
  "status": 400,
  "code": "validation_failed",
  "detail": "One or more fields are missing or invalid.",
  "errors": [
    {
      "path": "email",
      "message": "Invalid email"
    }
  ],
  "docs": "https://sisobuilders.com/developers"
}
```

| code | status | meaning |
| --- | --- | --- |
| validation_failed | 400 | A field or query parameter is invalid; `errors[]` says which |
| invalid_json | 400 | The request body is not JSON |
| not_found | 404 | No such project or endpoint |
| rate_limited | 429 | Slow down; `Retry-After` says how long |
| method_not_allowed | 405 | Wrong HTTP method for the path |
| internal_error | 500 | Something failed on our side; retry later |

## Rate limits

- Reads (`GET /api/v1/*`): 120 requests per minute per IP.
- Inquiries: 3 per 10 minutes per IP. Sandbox inquiries: 30 per 10 minutes per IP.
- Every response carries the IETF `RateLimit` and `RateLimit-Policy` fields plus `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds); a 429 adds `Retry-After`.

## Pagination

List endpoints are cursor-paginated. Ask for up to 50 items with `?limit=`; the response's `page.nextCursor` is opaque, pass it back as `?cursor=` until it comes back `null`. `page.total` is the full count for the filter.

## Versioning and deprecation

- The major version is in the path: `/api/v1`. Additive changes (new fields, new endpoints, new enum values) can ship at any time; clients should ignore fields they do not know.
- A breaking change ships as a new path version. The previous version keeps working for at least six months after the new one is announced.
- A deprecated version announces its end on every response with `Deprecation` and `Sunset` headers (RFC 9745 / RFC 8594) and a note in this section.

## MCP servers

Two Model Context Protocol servers over Streamable HTTP, no authentication. [/mcp](https://sisobuilders.com/mcp) is the product server (browse the portfolio, check the service area, request an estimate). [/mcp/docs](https://sisobuilders.com/mcp/docs) is the documentation server (read any page as markdown, search the site) and also exposes the pages as MCP resources. The server card at [/.well-known/mcp/server-card.json](https://sisobuilders.com/.well-known/mcp/server-card.json) lists both with their tools.

- `list_projects` (product, read-only): Lists the completed remodeling projects SISO Builders has published, optionally filtered by room type. Each item has a slug, title, category, city, summary and page URL.
- `get_project` (product, read-only): Returns one published project by slug: title, category, city, summary, page URL and the Instagram post it was shared in.
- `list_services` (product, read-only): Lists the remodeling services SISO Builders offers (kitchens, bathrooms, tile and flooring, feature walls, whole-home remodels, custom carpentry) with a one-line description and the work-page URL for each; slug narrows it to one service.
- `get_service_area` (product, read-only): Returns the region and the cities SISO Builders serves in South Florida, so an agent can check whether an address is covered before requesting an estimate; pass city to get a listed: true/false answer for one city.
- `get_faq` (product, read-only): Returns the published frequently asked questions and answers about service area, licensing, timelines and permits; query keeps only the entries matching a keyword.
- `request_estimate` (product): Submits a free on-site estimate request to SISO Builders on behalf of a homeowner. Creates a real inquiry and emails the team unless dry_run is true, so confirm the details with the homeowner first.
- `list_pages` (docs, read-only): Lists every public page of sisobuilders.com with its markdown URL, so an agent can pick what to read; kind narrows it to the fixed pages or the project pages.
- `read_page` (docs, read-only): Returns a page of sisobuilders.com as markdown (frontmatter plus body): home, work, a project, about, contact, privacy or developers.
- `search_site` (docs, read-only): Keyword search over the site: pages, services, FAQ answers and published projects. Returns ranked matches with a snippet and the page URL.
- `get_llms_txt` (docs, read-only): Returns /llms.txt, the concise index of the whole site written for language models, or with section one of the per-area indexes (/developers/llms.txt, /work/llms.txt).

```json
{
  "mcpServers": {
    "sisobuilders": {
      "url": "https://sisobuilders.com/mcp"
    },
    "sisobuilders-docs": {
      "url": "https://sisobuilders.com/mcp/docs"
    }
  }
}
```

## Browser agents (WebMCP)

The home, work and contact pages register the same six product tools on `document.modelContext` (falling back to `navigator.modelContext`) for browser agents, and the contact form is a declarative WebMCP tool named `request-estimate`. The form has no `toolautosubmit`: the homeowner reviews before it is sent.

## Discovery and metadata

- [llms.txt](https://sisobuilders.com/llms.txt): the site index for language models; per-area indexes at [/work/llms.txt](https://sisobuilders.com/work/llms.txt) and [/developers/llms.txt](https://sisobuilders.com/developers/llms.txt).
- Markdown twins: [/index.md](https://sisobuilders.com/index.md) and `<page>.md` for every page; the same via `Accept: text/markdown`; a structured JSON view at [/?mode=agent](https://sisobuilders.com/?mode=agent).
- [openapi.json](https://sisobuilders.com/openapi.json) and the RFC 9727 [API catalog](https://sisobuilders.com/.well-known/api-catalog).
- [ARD catalog](https://sisobuilders.com/.well-known/ard.json) of every agentic resource here, and the [agent-skills index](https://sisobuilders.com/.well-known/agent-skills/index.json) with installable SKILL.md files.
- [MCP server card](https://sisobuilders.com/.well-known/mcp/server-card.json), [auth.md](https://sisobuilders.com/auth.md), [pricing.md](https://sisobuilders.com/pricing.md), [sitemap.xml](https://sisobuilders.com/sitemap.xml) and the NLWeb [schema map](https://sisobuilders.com/schemamap.xml) with a JSON-LD feed of the business, services and projects.
- [/ask](https://sisobuilders.com/ask): an NLWeb-style question endpoint (POST JSON `{"query": "…"}`, SSE with `prefer.streaming`).

## Authentication

None. There are no credentials to obtain, so there is no OAuth server, no protected-resource metadata and no 401 flow to discover. The only authenticated area of the site is the owner admin at `/admin`, which is not for agents. Details in [auth.md](https://sisobuilders.com/auth.md).

## Fair use

The API exists to help homeowners in our service area find and reach us. Read as much as you like within the rate limits; create inquiries only for a real person who asked for an estimate, and use the sandbox for everything else.
