Read your Fractional Teams reports programmatically, and give AI agents scoped access to them over the Model Context Protocol.
A public demo workspace (“Meridian Workspace”, illustrative sample data) is open without any credentials, so you can explore the full toolset before signing up. Just call the API or MCP without a key, or use the literal token demo:
curl https://portal.fractionalteams.com/api/v1/me
# → the Meridian demo workspace, full access
Real access uses a per-user API key, a bearer token that starts with ftpk_. Each key belongs to one portal user and inherits that user’s access exactly (see Scopes below). Portal users manage their own keys on their account page (create, revoke, reissue, delete, up to 3 active keys per user), and account admins can also issue them. Key management is deliberately not exposed through the API or MCP: a leaked key can read what its user can read, but can never mint or rotate credentials.
Getting a key: a portal admin creates one for you under Admin → the client → Users → Create API key. The raw key is shown once at creation. Send it as a bearer token:
curl -H "Authorization: Bearer ftpk_your_key_here" \
https://portal.fractionalteams.com/api/v1/me
Keys are read-only plus lead-marking. No key can create, edit, delete, or release a report; those stay inside the admin portal. A revoked key or disabled user stops working immediately.
A key sees only what its user is allowed to see:
plan gates whether action plans are visible at all; a plan item also needs its category in scope):
seoaeogeosmmoutreachpaid_mediaplan.
Report content outside the key’s scope is filtered out server-side; reports with no in-scope content are invisible.GET /me reports this as outreach_owner: null means the user sees every salesperson’s leads in their outreach scope; a value (e.g. jane-smith) means they see only that person’s lead cards, and lead-marking follows the same restriction. A restricted user viewing a report that carries no leads attributed to their owner sees no outreach section at all (fail-closed).All three are properties of the portal user, set only by a Fractional Teams admin: every key a user holds inherits them at request time, so changing a user’s access instantly applies to all of their existing keys, and nothing on the API surface can widen or narrow access. To request per-salesperson keys (or any access change), ask your Fractional Teams contact to configure the users accordingly.
Cross-client access is impossible: a key only ever reaches its own client’s published reports.
Base URL https://portal.fractionalteams.com/api/v1. JSON responses; 404 for anything outside your access, 403 for a capability your key lacks on your own data.
| Method & path | What it returns |
|---|---|
GET /me | Your client, user, scopes, and permissions. |
GET /reports | Published reports you can see (newest first), each with the sections visible to you. |
GET /reports/:id | Metadata for one report. |
GET /reports/:id/html | The report’s HTML, filtered to your scope. |
GET /reports/:id/sections/:key | One section’s HTML (seo, aeo, geo, smm, outreach, paid_media, plan). |
GET /lead-status | Outreach lead flags (requires the outreach scope). Each row carries owner, the salesperson slug the lead is attributed to (null if unattributed), so per-salesperson grouping needs no HTML parsing. |
GET /leads | The structured window of recent outreach leads (activity in the ~30 days before the latest report): per lead, the conversation summary, last_message (at/from/text), LinkedIn profile_url, owner, last_activity_at, and current status. Requires the outreach scope; own-leads-only keys see only their own rows. |
GET /readiness | The latest Fractional Teams agent-readiness scan of each of your domains: our 0–100 score and grade, the Find / Read / Act breakdown, the ranked fix list, and a separate conformance reading checked against the AgentReady standard v1.0. ?target= for one domain, ?history= for earlier rows, ?engine=ora for the ora.ai calibration read. Requires the aeo scope. Read-only; scans run weekly. |
GET /readiness/:scanId | One scan in full: the summary plus every check with its status, points, finding, recommendation and evidence. |
GET /paid-media | Your connected ad accounts (Reddit Ads, LinkedIn Ads), each with every campaign and its most recent pulled figures: impressions, clicks and spend over a rolling 30-day window, with the pull time. ?platform=reddit|linkedin for one platform. Requires the paid_media scope. Read-only; the pull runs daily, so figures are up to a day old. |
GET /paid-media/campaigns/:campaignId/history | One campaign’s pull history as a chronological series (each pull’s 30-day window, oldest first). ?since=YYYY-MM-DD and ?limit= narrow it; default is the most recent 90 pulls. |
POST /leads/:conversationId/resolve | Mark a lead replied-outside-LinkedIn (requires lead-marking). |
POST /leads/:conversationId/unresolve | Undo that mark. |
The same capabilities are exposed as Model Context Protocol tools, so AI agents (Claude and others) can work with your reports directly.
https://portal.fractionalteams.com/mcpftpk_ bearer key, or nothing / demo for the sample workspace.claude mcp add --transport http portal \
https://portal.fractionalteams.com/mcp \
--header "Authorization: Bearer ftpk_your_key_here"
Settings → Connectors → Add custom connector → URL https://portal.fractionalteams.com/mcp, with your key as a bearer token.
| Tool | Purpose |
|---|---|
get_me | Your client, scopes, and permissions. |
list_reports | Published reports you can see. |
get_report | Metadata for one report. |
get_report_html | A report’s scope-filtered HTML. |
get_report_section | One section of a report. |
get_lead_status | Outreach lead flags. |
get_recent_leads | Recent leads with conversation summary, last message, profile link, owner, and status. |
get_agent_readiness | Latest agent-readiness scan per client domain: our score, Find / Read / Act breakdown, ranked fixes, and a conformance reading checked against the AgentReady standard v1.0 (needs the aeo scope). |
get_agent_readiness_scan | One agent-readiness scan in full, every check with its finding and evidence (needs the aeo scope). |
get_paid_media | Connected Reddit Ads and LinkedIn Ads accounts, each campaign with its latest pulled 30-day impressions, clicks and spend (needs the paid_media scope). |
get_paid_media_history | One campaign’s pull history as a chronological series (needs the paid_media scope). |
mark_lead_replied_outside | Mark a lead as replied outside LinkedIn. |
unmark_lead | Undo a lead mark. |
For agents and tooling, the same information in the formats they read first:
| File | What it is |
|---|---|
/openapi.json | OpenAPI 3.1 description of the REST API: every endpoint, response schema, the typed error object, named scopes in the security scheme, versioning policy and rate-limit headers. |
/.well-known/mcp/server-card.json | MCP server card: endpoint, transport, auth and the tool list, readable before connecting. |
/llms.txt | Navigation index for language models. |
/agents.md | When to use the portal, which surface to pick, and the rules an agent must respect. |
/auth.md | Step-by-step credential walkthrough (discover, claim, use, errors, revocation). |
/.well-known/oauth-protected-resource | RFC 9728 protected-resource metadata: bearer method and supported scopes. Also referenced from every 401 via WWW-Authenticate. |
/.well-known/api-catalog | RFC 9727 API catalog (linkset) of the REST and MCP surfaces. |
/.well-known/ard.json, /.well-known/agent-skills/index.json, /.well-known/agent-card.json | Agentic Resource Discovery catalog, Agent Skills index and A2A agent card, all pointing at the same two endpoints. |
Rate limits are signalled on every API response with the IETF RateLimit-Limit / RateLimit-Remaining / RateLimit-Reset headers; a 429 carries Retry-After. The API is versioned in the path (/api/v1); a breaking change would ship as /api/v2 with v1 kept for at least six months and Deprecation / Sunset headers announcing the timeline.