folio.Agent APIOpen workspace

Folio Agent API

Read saved website checks and search observations. Reuse recent results or request a new evaluation through one API.

Use /api/v1 on this Folio server. Locally, set FOLIO_BASE_URL=http://localhost:3001. Use your deployed HTTPS origin after production setup.

Send a Folio key in Authorization: Bearer <FOLIO_API_KEY>. Each key accesses only its owner’s workspace.

Connect your coding agent

Use Folio’s authenticated MCP server to inspect your website, read search evidence, and plan changes in Codex or Claude Code. Create a key below and keep it in the client’s environment as FOLIO_API_KEY.

Endpoint: https://usefolio.site/api/mcp. Use http://localhost:3001/api/mcp when connecting a local coding client to local Folio.

Codex

[mcp_servers.folio]
url = "https://usefolio.site/api/mcp"
bearer_token_env_var = "FOLIO_API_KEY"

Claude Code

{
  "mcpServers": {
    "folio": {
      "type": "http",
      "url": "https://usefolio.site/api/mcp",
      "headers": {
        "Authorization": "Bearer ${FOLIO_API_KEY}"
      }
    }
  }
}

Start with: “Use Folio to inspect my website’s saved SEO and visibility evidence, then propose changes in this repository.” Saved reports use read; new evaluations need evaluate; fresh DataForSEO lookups need seo. The client can edit your local code using its own tools.

In keyword run settings, enable search and backlinks to authorize one SEO lookup for the selected website. Repeated sandbox tool calls reuse the report. This needs a deployed public endpoint configured on Folio.

Freshness and run status

The default freshness window is 24 hours. Override maxAgeSeconds per request, from 0 to 604800.

Request observationPOST with the saved website or question ID
Check saved evidenceMatching result within 24 hours?
Yes · return itNo new evaluation
No · start a runOr reuse matching active work

GET only reads saved data. POST /observations/ensure can start paid work and needs the evaluate permission. Reuse the same Idempotency-Key and body when retrying; changing the key is a new request.

A 202 response points to the saved run. Read its pollUrl, and use /reconcile to retrieve existing remote progress. A cancelled or failed attempt stays in history. Replaying frozen website evidence does not make its capture newer.

POST/api/v1/observations/ensure

Get a fresh observation

Reuse a sufficiently recent result or matching active run; otherwise reserve and start one new evaluation. This request can incur usage charges.

Required permission: evaluate

Request

curl -X POST "$FOLIO_BASE_URL/api/v1/observations/ensure" \
  -H "Authorization: Bearer $FOLIO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: research-request-001" \
  --data '{
  "kind": "keyword",
  "caseId": "case_example",
  "maxAgeSeconds": 86400
}'

Response structure

Illustrative excerpt
{
  "disposition": "started",
  "freshness": {
    "maxAgeSeconds": 86400,
    "observedAt": null,
    "ageSeconds": null,
    "fresh": false
  },
  "run": {
    "id": "run_example",
    "kind": "keyword",
    "status": "running",
    "pollUrl": "/api/v1/runs/keyword/run_example"
  }
}
Observation parameters
ParameterMeaning
kindwebsite for captured-page checks, or keyword for search recommendations.
websiteId / caseIdUse the corresponding ID returned by your owned websites or benchmark-cases list. Send exactly one.
maxAgeSecondsDefaults to 86400. Only a completed matching observation can be fresh.
Reading outcomes and progress
fresh_saved
A saved result meets the requested age and configuration.
existing_active / started
Follow the saved run. Neither means that verification passed.
missing
No matching result exists. Read requests never create one.
requires_action
Inspect the existing attempt. Do not automatically create a replacement.
completed / failed / cancelled
Recorded terminal states. Read the checks and coverage, not just the status.

API keys

Create a read key for saved evidence, or allow explicit evaluation requests. The key is shown once; only its hash is stored.

Checking your workspace…

Errors and limits

Failures return {"error":{"code":"…","message":"…"}}. Keep unknown measurements and costs as null.

401 / 403
Check the key’s lifetime, permissions, and account access.
404
The record is unavailable to this key’s owner.
409
Inspect the existing request or active run. Never retry ambiguous creation with a new key.
429
Keys allow 60 requests per minute. Honor Retry-After when supplied. Evaluation allowances also apply; denied requests keep their idempotency outcome.
503
Retrieve existing state before deciding whether to retry.

Search recommendation positions describe the saved answer for a particular question. Page verification checks measure captured evidence. They remain separate in API responses.