# Pluto - agent onboarding

You are an AI agent (Claude, GPT, or similar). This file tells you how to onboard
yourself onto Pluto and start making calls. Everything below is a real, live endpoint.

## What Pluto is

Pluto is a marketing API for AEO, SEO, GBP, ads, content, reviews, and social, plus a
set of packaged AI workflows (one-shot LLM tasks). You call it over plain HTTPS with a
bearer key, or as tools over a hosted MCP server.

- Base API URL: `https://api.joinpluto.com/v1`
- Auth: `Authorization: Bearer <api_key>` on every request.
- Hosted MCP URL: `https://api.joinpluto.com/v1/mcp`

## 1. Mint your own key (no signup form, no card)

`POST /v1/checkout/free` is public (no auth). Give it an email and an optional name; it
mints a tenant plus a live API key and returns the raw key exactly once.

```bash
curl -X POST https://api.joinpluto.com/v1/checkout/free \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "name": "Acme Inc"}'
```

The `201` response looks like:

```json
{
  "tenant_id": "acme-1a2b3c4d",
  "tier": "free",
  "api_key": "sk_live_...",
  "api_key_meta": { "id": "...", "key_prefix": "sk_live_", "scopes": ["aeo:read", "..."] },
  "warning": "Store this key - it cannot be recovered."
}
```

Read the key from the `api_key` field (not `key`). Pluto stores only a hash, so save it now.

Notes:
- The email must be unique. A repeat email returns `409 already_exists` instead of a second key.
- Free signups are rate-limited per IP and capped per day, so mint once and reuse the key.
- `POST /v1/api-keys` mints additional keys but needs an existing key with `api-keys:write`,
  which the free tier does not carry. Use `POST /v1/checkout/free` for your first key.

Then export it:

```bash
export PLUTO_API_KEY=sk_live_...
```

## 2. Confirm auth

`GET /v1/usage` is a cheap read that confirms the key works and shows your plan and quota.

```bash
curl https://api.joinpluto.com/v1/usage \
  -H "Authorization: Bearer $PLUTO_API_KEY"
```

## 3. Add the MCP server (optional but recommended)

If you speak Model Context Protocol, point your client at the hosted server and every
endpoint becomes a callable tool. No HTTP glue to write.

```json
{
  "mcpServers": {
    "pluto": {
      "url": "https://api.joinpluto.com/v1/mcp",
      "headers": { "Authorization": "Bearer sk_live_..." }
    }
  }
}
```

- Transport: HTTP, JSON-RPC 2.0 (one request maps to one response).
- Discover tools with `tools/list`, invoke with `tools/call`.
- Tools: 27 curated tools spanning social, ads, SEO, AEO, content, reviews, GBP,
  local SEO, media, inbox, JobPins, and agent runs, plus tools auto-generated from
  the OpenAPI spec for the rest of the API.

```bash
curl https://api.joinpluto.com/v1/mcp \
  -H "Authorization: Bearer $PLUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

## 4. What you can call

Only the surfaces below exist. The verb list is drawn from the live routes. Each is
tagged `[free]` (a free key can call it) or `[paid]` (a free key gets `403 forbidden`;
needs a paid key with a card). Section 5 explains why.

- AEO (answer-engine visibility): scan across eight AI platforms `[free]`; read gaps,
  blindspots, and share-of-voice `[free]`; generate schema, generate `llms.txt`, and
  propose auto-fixes `[paid]`.
- SEO: read content decay, cannibalization, and cached rankings `[free]`; live rank
  check, local grid, heatmap, and keyword tracking (these fire paid SERP lookups) `[paid]`.
- GBP (Google Business Profile): audit and metrics reads `[free]`; post `[paid]`.
- Content: reads `[free]`; grounded generation, article write, distribute, and publish
  to WordPress or Webflow `[paid]`.
- Social: post, bulk post, list connected accounts `[paid]`.
- Ads: create and manage campaigns, deploy, pause, resume, optimize `[paid]`.
- Reviews: list, respond, request `[paid]`.
- Agents (packaged AI workflows): run one, poll or stream a run `[paid]`.
- Sites (register/verify), connect (start OAuth), tenant settings, and usage `[free]`.

The URL namespace `agents` holds the packaged AI workflows. These are one-shot LLM
tasks, not autonomous agents - you trigger one and read the result. They are paid.

### Example - run an AEO scan (`POST /v1/aeo/scan`) [free]

Asks the AI answer engines your queries and records whether the brand shows up. Runs
asynchronously and returns `202 Accepted` with a run to poll. Requires the `aeo:scan`
scope, which a free key carries. It is metered as an agent run, so it draws down the
small monthly agent-run allowance (see section 5).

```bash
curl -X POST https://api.joinpluto.com/v1/aeo/scan \
  -H "Authorization: Bearer $PLUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "brand": "Acme Plumbing",
    "queries": ["best plumber in Austin", "emergency plumber near me"],
    "platforms": ["chatgpt", "perplexity"]
  }'
```

`brand` (string, required), `queries` (string array, at least one, required), and
`platforms` (optional; any of `chatgpt`, `claude`, `gemini`, `perplexity`, `grok`,
`deepseek`, `metaai`, `ai_overview` - omit to scan all eight). Poll the returned
`poll_url` (`GET /v1/agents/runs/{id}`) until `status` is `completed`.

### Example - check a keyword rank (`POST /v1/seo/rank`) [paid]

A live SERP lookup for one keyword and domain. It fires a paid DataForSEO request, so it
requires the `seo:write` scope and a paid key - a free key gets `403 forbidden` here
before any spend. Shown because the request shape is a common one you will reach for once
you upgrade.

```bash
curl -X POST https://api.joinpluto.com/v1/seo/rank \
  -H "Authorization: Bearer $PLUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "keyword": "emergency plumber austin",
    "domain": "acmeplumbing.com",
    "location": "United States",
    "device": "desktop"
  }'
```

`keyword` (string, required), `domain` (string, required, no protocol), `location`
(optional, defaults to `United States`), `device` (optional, `desktop` or `mobile`,
defaults to `desktop`).

## 5. Free tier: look and scan, no card

The free tier is for looking and scanning. It needs no card, and its scope set is
confined at request time so anything that spends real money returns `403 forbidden`
to a free key before the spend.

What a free key CAN do:

- AEO citation scans (`aeo:scan`) - see whether a business shows up in AI answers.
- SEO reads that cost $0: content decay and cannibalization off your own Search Console
  data, plus cached rankings. (Live SERP checks are paid - see below.)
- GBP reads (audit, metrics), content reads, and your own account and usage reads.
- Setup writes so you can finish onboarding: register and verify a site, save tenant
  settings, and start an OAuth connect.

Included scopes (the ceiling; not a wildcard): `aeo:read`, `aeo:scan`, `seo:read`,
`gbp:read`, `content:read`, `sites:read`, `sites:write`, `tenant:read`, `tenant:write`,
`connect:read`, `connect:write`, `usage:read`, `api-keys:read`.

What needs a PAID key (a free key gets `403 forbidden`):

- Anything that GENERATES: content and articles, AEO fixes, media.
- Anything that DEPLOYS to a platform: ads, social posts, GBP posts, review responses.
- Anything that RUNS an AI workflow: the packaged agents and workflows.
- Live SERP lookups (rank, grid, heatmap, keyword tracking) - they bill DataForSEO, so
  they sit behind `seo:write`.

Free quota (for the reads and scans it can make):

- 1,000 actions per month.
- AEO scans are metered as agent runs; the free monthly agent-run allowance is small (5).
- a hard $25 spend ceiling per period (billable calls fail closed once hit).
- 60 requests per minute.

Paid tiers (`POST /v1/checkout/{hobby|pro|scale|agency}`) return a Stripe Checkout URL
and lift both the scope confinement and the quotas; Enterprise is a sales contact at
`sales@joinpluto.com`.

## 6. Errors and metering

- Every error is JSON with a stable machine-readable `code` (for example `rate_limited`,
  `quota_exceeded`, `already_exists`).
- Each metered request is one action. Agent runs and workflow runs count against their
  own quotas too. Once any quota or the spend cap is exhausted, billable calls return
  `402 quota_exceeded` until the period resets or you upgrade.
- Watch live numbers at `GET /v1/usage`.

Full human docs: https://docs.joinpluto.com  (agent quickstart: /agent-quickstart)
