

Tiny Solutions publishes its public pages, a versioned public API, and one read-only MCP server for outside apps: AI apps such as Claude, ChatGPT, and Perplexity. There is no public write API. The index of every public page is [llms.txt](/llms.txt).

## Markdown pages [#markdown-pages]

Send `Accept: text/markdown` to read a page as Markdown. The homepage and every docs page answer with `Content-Type: text/markdown` and `Vary: Accept`. A browser that asks for `text/html` gets the same page as HTML.

```bash
curl -H 'Accept: text/markdown' https://tinysolutions.app/
```

A docs address also answers as Markdown with `.md` added, for example `/docs/developers/outside-apps.md`. Early Intervention terms are under [/early-intervention.md](/early-intervention.md).

## Public API [#public-api]

The public API is at `/api/v1` and needs no key. Every answer is JSON.

| Endpoint                           | Returns                                                                    |
| ---------------------------------- | -------------------------------------------------------------------------- |
| `GET /api/v1/search?query=<words>` | Matching docs pages, headings, and passages, best first. Each has a `url`. |
| `GET /api/v1/docs?page=<path>`     | One docs page, such as `children/referrals`, with its body as Markdown.    |
| `GET /api/v1/terms`                | Every New York Early Intervention term, with a summary.                    |
| `GET /api/v1/terms/<slug>`         | One term in full, with its sources.                                        |
| `GET /api/v1/health`               | Whether the app is up, and the commit it serves.                           |

```bash
curl 'https://tinysolutions.app/api/v1/search?query=referral'
```

### Versioning [#versioning]

The version is in the path. A breaking change ships as a new version, such as `v2`, at a new path, and `/api/v1` keeps its contract. Before a version is retired, its responses carry `Deprecation` and `Sunset` headers (RFC 9745, RFC 8594) for at least 90 days.

### Rate limits [#rate-limits]

The API allows 60 requests a minute from one IP address. Each server instance keeps its own count, so read the headers rather than count requests yourself. Every answer carries the IETF RateLimit header fields:

```text
RateLimit-Policy: "default";q=60;w=60
RateLimit: "default";r=59;t=42
```

`r` is the requests left and `t` the seconds until the window resets. Past the limit the answer is 429 with `Retry-After`.

## OpenAPI [#openapi]

[/openapi.json](/openapi.json) describes the public API in OpenAPI 3.1, with an `operationId`, a description, typed parameters, and JSON response schemas for each endpoint. While the MCP server is on, it also describes the server's endpoint and its OAuth 2.1 security scheme, with the authorization and token addresses and the `tiny:read` scope.

## MCP server [#mcp-server]

Outside apps read one agency's records through a read-only MCP server. It uses the streamable HTTP transport and OAuth 2.1 with PKCE, with the `tiny:read` scope. Its Tools are `find_children`, `read_child`, and `read_my_reminder`. Each Tool reads only what the signed-in Member can open in the app, and each call writes one audit row.

The server is off until the environment switch turns it on. Then each agency's Owner turns it on for that agency in **Settings › General** under **Let outside apps read**. The Owner confirms that the outside apps staff connect are covered by a business associate agreement. While the server is on, its MCP Server Card is at `/.well-known/mcp/server-card.json` and is listed in `/.well-known/ai-catalog.json`.

## Errors [#errors]

An API error is RFC 9457 problem details, in JSON, with `Content-Type: application/problem+json`. It has `type`, `title`, `status`, `detail`, and `instance`, plus Tiny's `code` and `hint`.

```json
{
  "type": "https://tinysolutions.app/docs/developers/outside-apps#not-found",
  "title": "Not found",
  "status": 404,
  "detail": "/api/nothing-here is not an endpoint of this API.",
  "instance": "/api/nothing-here",
  "code": "not_found",
  "hint": "Read https://tinysolutions.app/openapi.json for the public endpoints."
}
```

### not\_found [#not-found]

Status 404. No endpoint or page has this address. Read [/openapi.json](/openapi.json) for the endpoints, or [llms.txt](/llms.txt) for the pages. A page address that does not exist answers 404 too, as Markdown when the request asks for `text/markdown`.

### missing\_query [#missing-query]

Status 400. `/api/v1/search` was called without words to search for. Add `?query=<words>`.

### unknown\_document [#unknown-document]

Status 404. No published docs page or term has this path or slug. List the terms with `/api/v1/terms`, or search with `/api/v1/search`.

### rate\_limited [#rate-limited]

Status 429. Too many requests came from one IP address. Wait the seconds in `Retry-After`, then try again.

### unauthenticated [#unauthenticated]

Status 401. The endpoint serves the signed-in web app and needs a sign-in session. Outside apps use the read-only MCP server instead.

