---
title: "Developers - Floral API, OpenAPI spec and MCP server | Floral"
description: "Floral developer guide: the public REST API at app.floral.so/api/v1 with an OpenAPI 3.1 spec, scoped personal access tokens, JSON errors, rate-limit headers, and the MCP server with OAuth 2.0 for Claude, ChatGPT and other AI clients."
canonical: https://floral.so/developers
---

# Developers - Floral API, OpenAPI spec and MCP server | Floral

> Floral developer guide: the public REST API at app.floral.so/api/v1 with an OpenAPI 3.1 spec, scoped personal access tokens, JSON errors, rate-limit headers, and the MCP server with OAuth 2.0 for Claude, ChatGPT and other AI clients.

Source: https://floral.so/developers

Developers

# Build on Floral: REST API, OpenAPI spec and an MCP server.

Everything a workspace knows is reachable by machines as well as people. The public REST API covers companies, people, briefings and meeting summaries and is described by an OpenAPI 3.1 document. The MCP server exposes 58 tools to Claude, ChatGPT, Codex and any other MCP-capable client. Both run with the permissions of the person who connected them, never more, and data stays in the EU.

[Open the OpenAPI spec](https://floral.so/openapi.json)[Read the docs](https://docs.floral.so)

## Getting started

You do not need to talk to sales to make a first call. Floral has a free 30-day trial, and a token is created by you, in the app. There is no separate sandbox: use a trial workspace with test data as your test environment.

1. [Start a free trial](https://floral.so/signup) (or sign in to an existing workspace at app.floral.so).
2. Open **Settings › Assistants › MCP** in the workspace, create a personal access token, pick the narrowest scopes and an expiry, and copy the token: it is shown once.
3. Call `GET /api/v1/workspaces/{workspaceSlug}/companies` with the token as a Bearer header. The [quickstart](https://docs.floral.so/developers/quickstart.md) walks through a relationship search next.
4. For an AI client, add `https://app.floral.so/mcp` as a remote MCP server and sign in with OAuth, or paste the same token.

## The public API

A versioned REST API over JSON. Every request is pinned to one workspace by its slug. Lists use cursor pagination, records carry ETags, and every operation in the spec has a unique operationId, typed parameters, response schemas and the scopes it needs, so a client generator or an LLM tool definition can be produced straight from the document. The spec at floral.so/openapi.json is the one the product publishes, cached hourly.

Base URL

`https://app.floral.so/api/v1`

OpenAPI

<https://floral.so/openapi.json> (OpenAPI 3.1.0, 22 operations)

Docs

<https://docs.floral.so>

API catalog

<https://floral.so/.well-known/api-catalog> (RFC 9727)

## Authentication and scopes

Authenticate with a personal access token created in your Floral workspace, sent as a Bearer token. A token is pinned to one workspace and carries one or more named scopes. Request the least you need: the spec declares the scopes under `x-scopes` on the security scheme and lists `x-required-scopes` on every operation.

curl https://app.floral.so/api/v1/workspaces/{workspaceSlug}/companies \
  -H "Authorization: Bearer $FLORAL_TOKEN" \
  -H "Accept: application/json"

### Scopes

- `contacts:read`Read companies, people, relationships and custom-field definitions in the workspace.
- `contacts:write`Create, update, archive and restore companies and people.
- `meetings:read`Read meetings, approved summaries and briefings.
- `meetings:write`Create meetings and submit meeting content for summarisation.

## Conventions

JSON errors

Every error is JSON: `{ "error": { "code", "message", "requestId" } }`. Codes are stable strings such as `INVALID_INPUT`, `NOT_FOUND` or `RATE_LIMITED`; quote the requestId when you write to us.

Concurrency

Updates are conditional. Send the record’s ETag in If-Match; a stale value gets 412, a missing one 428.

Pagination

List endpoints return a page and a cursor. Pass the cursor back to get the next page; no offsets.

Asynchronous work

Creating a briefing returns 202 with the briefing id. Poll it until the status is ready.

Markdown for agents

Every page on floral.so is also served as Markdown when you send `Accept: text/markdown`, and [llms.txt](https://floral.so/llms.txt) is the short guide to the site.

## Rate limits

Limits are per token and per minute, by class of operation. Every response carries the current limit and what remains; a 429 tells you when to retry.

| READ                    | 120 requests / minute |
| ----------------------- | --------------------- |
| WRITE / CREATE / ACTION | 60 requests / minute  |
| GENERATION              | 10 requests / minute  |

`X-RateLimit-Limit` · `X-RateLimit-Remaining` · `Retry-After` (429)

## MCP server

The Model Context Protocol server speaks Streamable HTTP and authenticates with OAuth 2.0 (the authorization server and supported scopes are published as RFC 9728 protected-resource metadata). Connections made through OAuth are read-only, and everything runs with the connected user’s workspace membership, role and feature access. Setup guides per client live in the [API and MCP](https://floral.so/features/api-and-mcp) overview and in the docs.

Endpoint

`https://app.floral.so/mcp`

RFC 9728

<https://app.floral.so/.well-known/oauth-protected-resource/mcp>

RFC 8414

<https://clerk.app.floral.so/.well-known/oauth-authorization-server>

server.json

<https://floral.so/server.json>

## Versioning and deprecation

The major version in the path (`/api/v1`) is the compatibility boundary. Keep the base path configurable, parse only the fields you need, and treat unknown fields and enum values as expected.

- Within a major version Floral may add operations, optional request fields and filters, response fields, and enum values where the field documentation allows it.
- A breaking change ships as a new major path with at least 180 days of overlap. Before the overlap starts we publish the replacement operation, migration steps, the effective date and a support channel.
- Deprecated operations are marked in the API reference with their replacement. A confirmed security or privacy issue may shorten the window.
- The full policy is in the docs: [Versioning and deprecation](https://docs.floral.so/developers/api/versioning.md).

## Operations

From the current OpenAPI document. The spec is the source of truth; this list is a map.

| Operation                    | Method | Path                                                 |
| ---------------------------- | ------ | ---------------------------------------------------- |
| searchRelationshipsV1        | GET    | /workspaces/{workspaceSlug}/relationships/search     |
| searchCompanyRegistryV1      | GET    | /workspaces/{workspaceSlug}/company-registry/search  |
| listCompaniesV1              | GET    | /workspaces/{workspaceSlug}/companies                |
| createCompanyV1              | POST   | /workspaces/{workspaceSlug}/companies                |
| getCompanyV1                 | GET    | /workspaces/{workspaceSlug}/companies/{id}           |
| updateCompanyV1              | PATCH  | /workspaces/{workspaceSlug}/companies/{id}           |
| archiveCompanyV1             | POST   | /workspaces/{workspaceSlug}/companies/{id}/archive   |
| restoreCompanyV1             | POST   | /workspaces/{workspaceSlug}/companies/{id}/restore   |
| listCustomFieldDefinitionsV1 | GET    | /workspaces/{workspaceSlug}/custom-field-definitions |
| listPeopleV1                 | GET    | /workspaces/{workspaceSlug}/people                   |
| createPersonV1               | POST   | /workspaces/{workspaceSlug}/people                   |
| getPersonV1                  | GET    | /workspaces/{workspaceSlug}/people/{id}              |
| updatePersonV1               | PATCH  | /workspaces/{workspaceSlug}/people/{id}              |
| archivePersonV1              | POST   | /workspaces/{workspaceSlug}/people/{id}/archive      |
| restorePersonV1              | POST   | /workspaces/{workspaceSlug}/people/{id}/restore      |
| listBriefingsV1              | GET    | /workspaces/{workspaceSlug}/briefings                |
| createBriefingV1             | POST   | /workspaces/{workspaceSlug}/briefings                |
| getBriefingV1                | GET    | /workspaces/{workspaceSlug}/briefings/{id}           |
| listSummariesV1              | GET    | /workspaces/{workspaceSlug}/summaries                |
| getSummaryV1                 | GET    | /workspaces/{workspaceSlug}/summaries/{id}           |
| updateSummaryV1              | PATCH  | /workspaces/{workspaceSlug}/summaries/{id}           |
| approveSummaryV1             | POST   | /workspaces/{workspaceSlug}/summaries/{id}/approve   |

## Building something on Floral?

Tell us what you are integrating. We can set up a workspace with demo data, and we read every message.

[Let's meet](https://floral.so/book-a-demo)[Contact](https://floral.so/contact)
