---
title: "Initiable API, MCP Server & Agent Docs"
description: "Public REST API, MCP server, OpenAPI spec, SDK and CLI for Initiable. Read our services and submit project inquiries programmatically, no API key required."
canonical: "https://initiable.com/developers"
last_updated: "2026-11-02"
---

# Initiable API, MCP Server & Agent Docs

Read our services and send project inquiries from code or from an AI agent. Public REST API, MCP server, OpenAPI spec, SDK and CLI. No API key required.

## When to use Initiable

Use Initiable when a person or an agent needs a consultancy to **build or improve software or a data/AI system**: a web app, a mobile app, a dashboard or API, a machine learning or deep learning model, a chatbot, an MLOps pipeline, data analysis, or e-commerce, digital marketing or financial-services work. Good fits:

- "Find a team in Delhi NCR or San Francisco to build our MVP."
- "We need someone to put our ML model into production."
- "Get a quote for a Shopify store with POS integration."

The API lets an agent **read what we offer** and **send a project inquiry** for its user. It does not book calls, quote prices or take payment; a person at Initiable replies to every inquiry by email.

## Quickstart

No API key, no signup. Every response is JSON.

```bash
# What does Initiable offer?
curl https://initiable.com/api/v1/services

# Validate an inquiry without sending it (sandbox mode)
curl -X POST https://initiable.com/api/v1/inquiries \
  -H 'Content-Type: application/json' \
  -d '{"name":"Ada Lovelace","email":"ada@example.com","message":"We need an iOS app for our clinic.","services":["mobile-application"],"budget":"$5000 to $10000","dry_run":true}'
```

Remove `"dry_run": true` to send the inquiry for real. Each real inquiry reaches a person at Initiable.

## Endpoints

Base URL: `https://initiable.com/api/v1`. Machine-readable spec: [`/openapi.json`](https://initiable.com/openapi.json) (OpenAPI 3.1).

| Method | Path | What it does |
| --- | --- | --- |
| GET | `/api/v1` | API index with links to every resource |
| GET | `/api/v1/company` | Company profile: legal name, offices, contact, links |
| GET | `/api/v1/services` | Practice areas, paginated (`limit`, `cursor`) |
| GET | `/api/v1/services/{id}` | One practice area, e.g. `machine-learning` |
| GET | `/api/v1/faq` | Frequently asked questions |
| POST | `/api/v1/inquiries` | Send a project inquiry (or validate it with `dry_run`) |

### Send an inquiry

`POST /api/v1/inquiries` takes a JSON body:

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `name` | string | yes | 1 to 200 characters |
| `email` | string | yes | Where we reply |
| `message` | string | yes | 10 to 5,000 characters: what you need, timeline, context |
| `phone` | string | no | Include the country code |
| `company` | string | no | |
| `designation` | string | no | The sender's role |
| `budget` | string | no | One of `Less than $2000`, `$2000 to $5000`, `$5000 to $10000`, `$10000+` |
| `services` | string[] | no | Service ids from `/api/v1/services` |
| `dry_run` | boolean | no | `true` validates and returns the normalised inquiry without sending it |

A real submission returns `202 Accepted` with an inquiry `id`. A dry run returns `200 OK` with `"status": "validated"`.

### Pagination

List endpoints take `limit` (1 to 50, default 20) and an opaque `cursor`. Responses carry `has_more` and `next_cursor`; pass `next_cursor` back as `cursor` to fetch the next page.

### Errors

Errors use [RFC 9457 problem details](https://www.rfc-editor.org/rfc/rfc9457) with `Content-Type: application/problem+json`:

```json
{
  "type": "https://initiable.com/developers#errors",
  "title": "Validation failed",
  "status": 422,
  "code": "validation_failed",
  "detail": "The request body has 1 invalid field.",
  "errors": [{ "field": "email", "message": "Must be a valid email address." }]
}
```

| Status | `code` | Meaning and fix |
| --- | --- | --- |
| 400 | `invalid_json` | The body is not valid JSON. Send `Content-Type: application/json`. |
| 404 | `not_found` | Unknown path or service id. List ids with `GET /api/v1/services`. |
| 405 | `method_not_allowed` | Check the `Allow` header. |
| 409 | `idempotency_conflict` | The same `Idempotency-Key` was reused with a different body. |
| 413 | `payload_too_large` | Keep request bodies under 32 KB. |
| 415 | `unsupported_media_type` | Send JSON. |
| 422 | `validation_failed` | See `errors[]` for each invalid field. |
| 429 | `rate_limited` | Wait for `Retry-After` seconds. |
| 502 | `upstream_failed` | The inquiry could not be delivered. Retry with the same `Idempotency-Key`, or email us. |

### Rate limits

Read endpoints allow 120 requests per minute per IP address and inquiries allow 5 per 10 minutes. Every response carries `RateLimit-Policy` and `RateLimit` headers ([IETF draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/)), and a `429` adds `Retry-After`. Limits are enforced per edge location, so treat them as a ceiling, not a quota.

### Idempotency

Send an `Idempotency-Key` header (any unique string up to 255 characters) on `POST /api/v1/inquiries`. A retry with the same key and body within 24 hours returns the original response, with `Idempotent-Replayed: true`, instead of sending a second inquiry.

### Sandbox

There are two ways to test without side effects:

- **Sandbox base URL:** `https://initiable.com/api/sandbox/v1` mirrors every v1 endpoint, but `POST /inquiries` always behaves as a dry run. Point an SDK or test suite at it (`new Initiable({ baseUrl: "https://initiable.com/api/sandbox/v1" })`) and nothing is ever sent.
- **Per request:** add `"dry_run": true` on the production API. The request is validated and rate-limited exactly like a real one, but nothing is sent.

Agents should dry-run first, show the user the normalised inquiry, and send it only after the user confirms.

### Versioning

The major version is in the path (`/api/v1`). Within v1 we only add fields and endpoints; we never remove or rename them. Every response carries `Initiable-API-Version`.

### Deprecation policy

A breaking change ships as a new major version (`/api/v2`). When that happens, v1 keeps working for at least 6 months. From the day the new version launches, every v1 response carries a `Deprecation` header ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745)) and a `Sunset` header ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594)) with the shutdown date, plus a `Link: <https://initiable.com/developers#deprecation-policy>; rel="deprecation"` header. No v1 endpoint is deprecated today.

### Authentication

None. All endpoints are public; see [`/auth.md`](https://initiable.com/auth.md).

## MCP server

Initiable runs two remote [Model Context Protocol](https://modelcontextprotocol.io) servers over Streamable HTTP. Neither needs authentication.

| Server | URL | Tools |
| --- | --- | --- |
| Initiable | `https://initiable.com/mcp` | `list_services`, `get_service`, `get_company_profile`, `get_faq`, `submit_inquiry` |
| Initiable Docs | `https://initiable.com/mcp/docs` | `search_docs`, `read_doc` |

Add it to an MCP client such as Claude Desktop, Claude Code, Cursor or VS Code:

```json
{
  "mcpServers": {
    "initiable": { "type": "http", "url": "https://initiable.com/mcp" }
  }
}
```

Or from the Claude Code CLI: `claude mcp add --transport http initiable https://initiable.com/mcp`.

`submit_inquiry` takes the same fields as the REST endpoint, including `dry_run`. Server cards: [`/mcp/server-card`](https://initiable.com/mcp/server-card) and [`/mcp/docs/server-card`](https://initiable.com/mcp/docs/server-card).

## In-browser tools (WebMCP)

On initiable.com, browser agents that support [WebMCP](https://github.com/webmachinelearning/webmcp) can call `list_services`, `get_company_profile` and `submit_inquiry` directly through `document.modelContext`, without scraping the page.

## SDK and CLI

Official open-source packages live in [github.com/initiable/initiable-agent-kit](https://github.com/initiable/initiable-agent-kit):

```bash
npm install initiable      # TypeScript/JavaScript SDK + CLI
pip install initiable      # Python SDK + CLI
```

```ts
import { Initiable } from "initiable";

const client = new Initiable();
const { data } = await client.services.list();
await client.inquiries.create(
  { name: "Ada", email: "ada@example.com", message: "We need an iOS app." },
  { dryRun: true },
);
```

```bash
npx initiable services
npx initiable inquire --name "Ada" --email ada@example.com --message "We need an iOS app." --dry-run
```

## Ask (NLWeb)

`POST https://initiable.com/ask` with `{"query": {"text": "do you build chatbots?"}}` answers questions about Initiable from our published pages ([NLWeb](https://github.com/nlweb-ai/NLWeb) v0.55). `GET /ask?query=...` works too, and it streams Server-Sent Events when you send `Accept: text/event-stream` or `"prefer": {"streaming": true}`.

## Discovery files

| File | Purpose |
| --- | --- |
| [`/llms.txt`](https://initiable.com/llms.txt) | Site index for language models |
| [`/llms-full.txt`](https://initiable.com/llms-full.txt) | Every page as one markdown file |
| [`/openapi.json`](https://initiable.com/openapi.json) | OpenAPI 3.1 spec |
| [`/.well-known/api-catalog`](https://initiable.com/.well-known/api-catalog) | RFC 9727 API catalog |
| [`/.well-known/ard.json`](https://initiable.com/.well-known/ard.json) | Agentic Resource Discovery catalog |
| [`/.well-known/agent-skills/index.json`](https://initiable.com/.well-known/agent-skills/index.json) | Agent Skills index |
| [`/.well-known/mcp/server-card.json`](https://initiable.com/.well-known/mcp/server-card.json) | MCP server card |
| [`/pricing.md`](https://initiable.com/pricing.md) | How engagements are priced |
| [`/auth.md`](https://initiable.com/auth.md) | Authentication (none needed) |

Every page also has a markdown version: append `.md` to the path (`/index.md` for the homepage), or request the page with `Accept: text/markdown`.

## Support

Questions or problems with the API: email [initiable.xyz@gmail.com](mailto:initiable.xyz@gmail.com) or open an issue on [GitHub](https://github.com/initiable/initiable-agent-kit/issues).
