Fluid Recall Plan API
The Plan API from Fluid Recall — 2 operation(s) for plan.
The Plan API from Fluid Recall — 2 operation(s) for plan.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/fluidrecall-com:fluidrecall-com-plan-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Fluid Recall Plan API
version: 0.0.0
description: 'System of record for spaced recall. One service with four doors: MCP at POST /mcp (also /api/mcp), Markdown /api/v1/agent and /api/v1/dev, and JSON /api/v1. Agents may use whatever works best. None is deprecated. JSON operations sit at the /api/v1 root (/due, /decks, /reviews). Request bodies are JSON. Markdown responses use Content-Type text/plain; the body is Markdown. MCP is stateless Streamable HTTP. Send Authorization: Bearer . No Mcp-Session-Id. The same MCP door speaks the ChatGPT MCP Events subset (events/list, events/subscribe, events/unsubscribe) with webhook-only delivery. Muse bootstraps a personal API token with POST /accounts or POST /bootstrap and keeps drilling. The bearer token is the tenant. This API decides what is due and when it is due next. Bootstrap, reviews, and unauthenticated reads are rate limited. HTTP 429 is retryable. ---'
servers:
- url: /api/v1
security:
- bearerAuth: []
- poppyDpop: []
tags:
- name: Plan
paths:
/plan/new-cards:
post:
operationId: previewDeadlinePlan
summary: Recommend newCardsPerDay from a deadline
description: 'Routine read. Does not write. Given a deadline and card counts, returns recommended newCardsPerDay (ceil of remaining new cards ÷ study days through the deadline, clamped to 0–9999). There is no silent default of 20. This is new-card trickle math. Review load grows, so treat the number as a floor: Muse may raise N or negotiate more study time. Call this before createDeck when the person has a deadline, and again after bulk card adds. Send remainingNewCards, totalCards, or deckId. When deckId is set, remaining new cards and current N come from that owned deck unless you override them. Another token''s deck is 404. Prefer a YYYY-MM-DD deadline so timezone does not shift the date. Create still requires an explicit newCardsPerDay; this call only helps you choose it.'
x-muse-action-class: read
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DeadlinePlanRequest'
responses:
'200':
description: Recommended N, days remaining, projected finish, on-track, and coaching.
content:
application/json:
schema:
$ref: '#/components/schemas/DeadlinePlan'
'400':
description: Invalid body or missing card counts.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or wrong token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: No deck with that id for this token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Plan
/plan/new-cards/apply:
post:
operationId: applyDeadlinePlan
summary: Set a deck's newCardsPerDay to the recommended value
description: Write. Computes the same plan as previewDeadlinePlan, then PATCHes that owned deck's newCardsPerDay to the recommended integer. Reuses updateDeck. deckId is required. Another token's deck is 404. Discuss the number with the person first. Do not apply in silence just to hit a date if they cannot study that many cards. Create still requires an explicit N.
x-muse-action-class: write
requestBody:
required: true
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DeadlinePlanRequest'
- type: object
required:
- deckId
properties:
deckId:
type: string
format: uuid
responses:
'200':
description: The plan and the patched deck.
content:
application/json:
schema:
$ref: '#/components/schemas/DeadlinePlan'
'400':
description: Invalid body.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Missing or wrong token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: No deck with that id for this token.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Plan
components:
schemas:
DeadlinePlan:
type: object
additionalProperties: false
required:
- deadline
- asOf
- asOfStudyDay
- timezone
- dayBoundaryHour
- remainingNewCards
- alreadyLearned
- totalCards
- calendarDaysUntilDeadline
- studyDaysUntilDeadline
- recommendedNewCardsPerDay
- currentNewCardsPerDay
- projectedFinishDateAtCurrent
- projectedFinishDateAtRecommended
- onTrack
- pace
- countsFromDeck
- applied
- deckId
- deck
- assumptions
- coaching
properties:
deadline:
type: string
description: Deadline study day as YYYY-MM-DD.
asOf:
type: string
description: UTC ISO-8601 timestamp ending in Z
asOfStudyDay:
type: string
description: Study day of asOf as YYYY-MM-DD.
timezone:
type: string
dayBoundaryHour:
type: integer
remainingNewCards:
type: integer
alreadyLearned:
type: integer
totalCards:
type: integer
calendarDaysUntilDeadline:
type: integer
studyDaysUntilDeadline:
type: integer
recommendedNewCardsPerDay:
type: integer
description: ceil(remainingNewCards / studyDaysUntilDeadline), clamped to 0–9999. Not a default of 20. A floor from the deadline.
currentNewCardsPerDay:
type:
- integer
- 'null'
projectedFinishDateAtCurrent:
type:
- string
- 'null'
description: YYYY-MM-DD of the last new-card introduction at the current N. Null if current N is missing or 0.
projectedFinishDateAtRecommended:
type:
- string
- 'null'
onTrack:
type:
- boolean
- 'null'
description: True when current N finishes remaining new cards by the deadline. Null when there is no current N.
pace:
type: string
enum:
- done
- overdue
- faster
- on_track
- slower
- unknown
countsFromDeck:
type: boolean
applied:
type: boolean
deckId:
type:
- string
- 'null'
format: uuid
deck:
type:
- object
- 'null'
description: The patched deck after apply. Null on preview.
assumptions:
type: array
items:
type: string
coaching:
type: string
DeadlinePlanRequest:
type: object
additionalProperties: false
required:
- deadline
properties:
deadline:
type: string
description: YYYY-MM-DD preferred. A UTC instant ending in Z is converted to the study day in timezone.
asOf:
type: string
description: UTC ISO-8601 timestamp ending in Z
timezone:
type: string
description: IANA name. Defaults to the account timezone.
dayBoundaryHour:
type: integer
minimum: 0
maximum: 23
remainingNewCards:
type: integer
minimum: 0
totalCards:
type: integer
minimum: 0
alreadyLearned:
type: integer
minimum: 0
skipWeekends:
type: boolean
studyDaysPerWeek:
type: integer
minimum: 1
maximum: 7
bufferStudyDays:
type: integer
minimum: 0
description: Reserve this many study days at the end of the window as review-only buffer.
currentNewCardsPerDay:
type:
- integer
- 'null'
minimum: 0
maximum: 9999
description: Compare this N to the recommendation. Omit to use the deck's effective N when deckId is set.
deckId:
type: string
format: uuid
description: Fill remaining new cards and current N from this owned deck unless you override them.
Error:
type: object
additionalProperties: false
required:
- code
- message
- retryable
properties:
code:
type: string
enum:
- BAD_REQUEST
- UNAUTHORIZED
- FORBIDDEN
- NOT_FOUND
- CONFLICT
- UNAVAILABLE
- RATE_LIMITED
message:
type: string
retryable:
type: boolean
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Personal Fluid Recall API token from POST /accounts (or POST /bootstrap). Save it for API calls. The operator break-glass secret is a different credential and cannot call drill operations.
poppyDpop:
type: http
scheme: DPoP
description: 'Personal Agent Protocol (Poppy v0.1) Session Token from POST https://fluidrecall.com/oauth/token, sent as Authorization: DPoP <token> with a DPoP proof header on every call. poppy:read allows reads and poppy:write allows changes; personal API token management is not available. See https://fluidrecall.com/.well-known/poppy.json and https://fluidrecall.com/docs/personal-agent-protocol.'