One brain for X. REST, MCP, CLI.

Everything the Xpert app does is callable: 199 operations for drafting in a voice, engagement prediction, scheduling, analytics, lead finding and engagement. One OpenAPI document, one MCP server, one CLI and one response envelope, behind API keys or OAuth 2.1.

Base URL https://api.xpert.so, every endpoint under /v1. JSON in, JSON out.

Quickstart

Four steps from zero to a scored draft. Base URL https://api.xpert.so. All responses are JSON.
  1. Create an API key

    Sign in at app.xpert.so, open Settings → Public API keys, and create a key. It starts with sk_live_ and carries every scope for your org. Treat it like a password.

    Send it on every call

    Authorization: Bearer sk_live_…
  2. Call the API

    Every endpoint lives under /v1 and answers with one envelope: success plus your data, or success:false with a message and a machine code.

    Request

    curl https://api.xpert.so/v1/me \
      -H "Authorization: Bearer sk_live_…"
  3. Draft in the owner's voice, then score it

    Compose returns text written from the account's own posting history. Predict scores any text against that history before anyone posts it.

    Requests

    curl https://api.xpert.so/v1/ai/compose \
      -H "Authorization: Bearer sk_live_…" -H "content-type: application/json" \
      -d '{"kind":"post","prompt":"what we shipped this week"}'
    
    curl https://api.xpert.so/v1/ai/predict \
      -H "Authorization: Bearer sk_live_…" -H "content-type: application/json" \
      -d '{"text":"spent 3 months posting commit logs. 11 views."}'
  4. Act on more than one X account

    An org can connect several accounts. List them, then pass x-account-id on any call; omit it for the most recently connected one.

    Requests

    curl https://api.xpert.so/v1/x/accounts -H "Authorization: Bearer sk_live_…"
    curl https://api.xpert.so/v1/drafts -H "Authorization: Bearer sk_live_…" -H "x-account-id: <id>"

Authentication

API keys for your own automation, OAuth 2.1 with PKCE for anything acting for a user. Both hit the same endpoints and the same scope model.

API key

Created in the app under Settings → Public API keys. Carries every scope for the org. Send it as a bearer token from your own scripts and servers.

Authorization: Bearer sk_live_…

OAuth 2.1

Authorization code with PKCE, dynamic client registration and scoped consent. Metadata at /.well-known/oauth-authorization-server.

read
Read & analytics
write
Authoring & publishing
engage
Engagement & automation
dm
DM outreach
admin
Account admin

The envelope

Every response carries success and a human-readable message; errors add a machine code.

Response bodies

{ "success": true,  "message": "Draft saved.", "id": "drf_…" }
{ "success": false, "message": "Start your free trial to use Xpert.", "code": "subscription_required" }

Codes to handle

subscription_required402
The org has no active plan or trial yet.
insufficient_credits402
Not enough credits; the body says what the action needed and the balance.
upgrade_required402
The plan does not include this feature, such as API access.
not_found404
The resource was not found.

Unknown site paths return a real 404, with a markdown body if you ask for text/markdown.

MCP server for agents

Every operation is also an MCP tool at https://mcp.xpert.so/mcp, behind OAuth.

Before authenticating, read the resources on the open discovery endpoint https://mcp.xpert.so/mcp/public: quickstart, tool index, OpenAPI and llms.txt.

Copy the connector URL

https://mcp.xpert.so/mcp

One OAuth sign-in connects your X account. No API key to paste.

Pick your app

Connect Claude

  1. Open Claude → Settings → Connectors.
  2. Click “Add custom connector”.
  3. Paste the connector URL above, then Connect.
  4. Sign in with Xpert and authorize once in your browser.
Open Claude connectors

WebMCP in the browser

Agents built into the browser can use Xpert with no key or connector: public tools on every page, and the signed-in user's own account inside the app. On in Chrome's WebMCP origin trial, or with chrome://flags/#enable-webmcp-testing.

The tools register on document.modelContext with typed inputs, so an agent calls them instead of clicking through screens.

The agent writes, Xpert checks the draft against the user's voice and fills the composer, and the user posts. None of the tools posts, schedules, sends or deletes anything, and only the post search spends a credit.

On every page

  • check_ai_phrasesThe AI phrases in a draft, scored, with swaps
  • count_x_charactersX's own character count, links as 23
  • find_free_toolsThe free tool for a job, with its link
  • get_xpert_pricingLive plans, prices and the trial

Signed in to the app

  • get_account_overviewFollowers, growth and the last 24 hours
  • list_draftsSaved drafts, with links into the composer
  • check_draftVoice match and the pre-flight check
  • open_in_composerFills the composer for the user to review
  • save_draftSaves a post or thread as a draft
  • get_reply_ideasFor You posts with replies drafted in the user's voice
  • get_weekly_readWhat worked last week and what to try next
  • get_voice_guideHow the user writes, as one guide
  • search_my_postsThe user's own posts on a topic (1 credit)

CLI

The same surface from a terminal. Pipe it, cron it, script it into a ship day. @xpertso/cli on npm
$ npm i -g @xpertso/cli$ xpert login$ xpert run network-opportunities$ xpert run autopilot-draft --prompt "what we shipped this week"$ xpert run analyze-profile --handle naval$ xpert run list-drafts --json | jq -r '.data[].id'$
Install
npm i -g @xpertso/cli, or run one command with npx @xpertso/cli. Node 18 or newer.
Sign in
xpert login opens xpert.so in your browser: OAuth with PKCE, no API key pasted into a terminal.
Every endpoint
Each API operation is xpert run <name>, and xpert run --help lists them all.
Scripting
Add --json for raw JSON on stdout and pipe it to jq. For anything unwrapped, xpert api GET /v1/posts calls the endpoint directly.

Discovery files

Machine-readable entry points, all public, all cacheable. Start at the API catalog if you are a crawler, at llms.txt if you are a model.

Sandbox and safety

There is no separate sandbox: calls run against a real X account and spend real credits. To explore safely, connect over OAuth with only the read scope, or read the tool index and spec on the open MCP endpoint first. Tool annotations (readOnlyHint, destructiveHint) and the x-read-only and x-destructive flags in the OpenAPI document are accurate.

A reply your code posts through POST /v1/timeline/post or a For you card goes straight to X with the write scope, like any post, and is metered. Replies and DMs that Xpert drafts on its own queue in the owner's approval inbox instead; the approval and DM endpoints refuse API keys, so a signed-in user, the CLI or a connected MCP client with the engage scope clears them. Sends are capped and spaced, and campaigns pause when X pushes back.

Questions or a key that needs rotating: contact@xpert.so.

Developer FAQ

Straight answers about testing, auth, cost, what agents can send, and where the full reference lives.

Is there a sandbox or test environment?

Not a separate one. Every call runs against a real connected X account and spends that org's credits. For safe exploration connect over OAuth with only the read scope: you get analytics, drafts, network intelligence and lead signals with no ability to publish, and the unauthenticated MCP discovery endpoint lets you read the spec and tool index before you authenticate at all.

API key or OAuth?

API keys are for your own scripts and servers: one org, every scope, no user consent screen. OAuth 2.1 with PKCE is for anything acting on behalf of a user (MCP clients, hosted agents): the user signs in with X, picks scopes, and can revoke access later. Dynamic client registration is supported, so agents can onboard without a manual app setup.

What are the rate limits and what does a call cost?

Calls are metered in credits rather than a published request quota. AI-backed operations (compose, predict, x-ray, image generation, lead finding) and live X searches spend credits included with the plan, and reads of your own data are free. A 402 with code insufficient_credits says what the action needed and your balance; subscription_required means the org needs to start a trial. The OpenAPI document tags each operation with its scope, and the pricing page lists what is included.

Can my agent post replies or DMs automatically?

Only by calling a publish endpoint itself. With the write scope, POST /v1/timeline/post and POST /v1/foryou/{id}/post put a reply on X straight away, like any post. Replies and DMs that Xpert drafts on its own wait in the owner's approval inbox instead, and the approval and DM endpoints refuse API keys: a signed-in user, the CLI or a connected MCP client with the engage scope has to approve them.

Where is the full list of endpoints?

The OpenAPI document at api.xpert.so/openapi.json is generated from the same manifest that powers the MCP tools and the CLI, so it is always complete. The MCP page groups the same surface by product area, and the MCP resource xpert://docs/tools is a markdown index of it.

The app is one client.
Yours can be the next.