REST API overview

The ForceVue REST API v1. Base URL, authentication, error envelope, pagination, rate limits, and versioning.

The ForceVue REST API lets you read and write your workspace data from your own code: initiatives, documents, context items, goals, search, and AI document generation. It is the same data you work with in the app, over plain HTTP with JSON.

This page covers the parts that apply to every endpoint. For a per-endpoint reference with request and response schemas and copyable curl examples, see the API reference.

Base URL and versioning

Every endpoint lives under a single versioned base path:

https://forcevue.com/api/v1

The API is versioned. v1 is the current version. Additive changes (a new field, a new endpoint) ship in place without a version bump. Breaking changes ship under a new path (/api/v2), so code written against v1 keeps working.

Authentication

Authenticate with an API key sent as a bearer token:

Authorization: Bearer fvk_live_…

Keys start with fvk_live_, are scoped to one workspace, and act on your behalf. The API accepts the bearer token only. There is no X-API-Key alias and no other auth method.

Create and manage keys in Settings. See API keys for how to create one, the shown-once rule, and the paid-plan requirement. A missing or invalid key returns 401. A key on a free workspace returns 403 with the code PAID_PLAN_REQUIRED.

A key is tied to its workspace, so you never pass an organization id. Every request reads and writes within the workspace the key belongs to.

Response envelope

Responses use the same envelope as the rest of ForceVue.

A success response wraps the payload in data and carries a meta block:

{
  "success": true,
  "data": { "id": "…", "title": "…" },
  "meta": {
    "requestId": "a1b2c3d4",
    "timestamp": "2026-06-12T16:00:00.000Z"
  }
}

An error response carries a human-readable error, a machine-readable code, and the same request fields:

{
  "error": "Resource not found",
  "code": "NOT_FOUND",
  "requestId": "a1b2c3d4",
  "timestamp": "2026-06-12T16:00:00.000Z"
}

requestId is also returned in the X-Request-ID response header, so you can quote it if you need help with a specific call.

A resource that does not exist in your workspace returns 404, not 403. The API does not confirm whether an id belongs to another workspace, so there is no existence oracle across tenants.

Pagination

List endpoints take limit and offset:

  • limit defaults to 20 and caps at 100.
  • offset is a zero-based row offset.

Lists are ordered newest first. The response puts the rows under items and a pagination block alongside them:

{
  "success": true,
  "data": {
    "items": [],
    "pagination": { "limit": 20, "offset": 0, "has_more": true }
  },
  "meta": { "requestId": "…", "timestamp": "…" }
}

has_more tells you whether another page exists without a separate count call. Increase offset by your limit to walk the next page.

Rate limits

API traffic shares your per-minute budget with the in-app surfaces, keyed to your account, so the API and the app draw from one budget per user.

  • CRUD endpoints use the general API bucket: 100 requests per minute.
  • Search uses the search bucket: 30 requests per minute.
  • Document generation uses your AI bucket, which is tiered by plan. See Usage & limits for the per-plan figures.

When you exceed a limit, the response is 429 with a Retry-After header telling you how long to wait, plus X-RateLimit-* headers describing the bucket. A 429 here is a short-term throttle, separate from your monthly generation quota.

Resources

ResourceWhat it covers
InitiativesCreate, read, update, archive, and delete initiatives
DocumentsCreate, read, update, and delete documents; body is markdown (see below)
Context itemsThe labeled notes that steer generation, at initiative or workspace scope
GoalsInitiative and workspace goals that steer generation
SearchQuery across your workspace content, optionally scoped to one initiative
GenerateGenerate a full document with AI from an initiative's context

Context items and goals exist at two scopes (initiative and workspace). Both endpoints take a scope field that selects the scope explicitly in the request and reflects it in the response, so one path covers both.

Document content is markdown

The API speaks markdown for document bodies. You never handle the editor's internal format. Reads return the body as content_markdown, and writes accept markdown that the API converts on the way in. Headings, lists, and tables survive the round trip.

Generating documents

POST /api/v1/generate runs a full AI generation from an initiative's context and returns the finished document as markdown. A few things to know:

  • It is synchronous. The request stays open until the document is written, so allow for a longer timeout than a normal CRUD call.
  • It consumes your monthly generation quota, the same quota the app uses. Each call is one generation, counted once. See Usage & limits.
  • One call is one generation. The endpoint does not retry a failed generation on your behalf, and one request never produces more than one document. If a call fails, you decide whether to call again.
  • Every call is recorded in your workspace activity, marked as coming from the API.

Creating a document with POST /api/v1/documents is different: it saves a document you provide (or an empty draft) and does not call the AI or touch your quota. Use /generate when you want ForceVue to write the content.

A first request

This lists your initiatives. Replace the key with one of your own.

curl https://forcevue.com/api/v1/initiatives \
  -H "Authorization: Bearer fvk_live_your_key_here"

To confirm a key works and see your usage, call the introspection endpoint, which returns your workspace, the key, and this month's generation usage:

curl https://forcevue.com/api/v1/me \
  -H "Authorization: Bearer fvk_live_your_key_here"

Where to go next