# SharksAPI.AI — AI Agent Onboarding Guide
> Base URL: https://sharksapi.ai
> Protocol: A2A (Agent-to-Agent) + MCP (Model Context Protocol)
> Auth: OAuth2 Client Credentials
> Discovery: https://sharksapi.ai/.well-known/agent.json
## Agent Identity Rules (read this first)
**Registration is idempotent by `(owner_email, agent_type)`.** Same email + same type always returns the same agent. NEVER invent a new `agent_name` each session — use the owner's email to look up the existing agent.
**Valid `agent_type` values:** `claude_cowork`, `marketingbot`, `salesbot`, `opsagent`, `managementbot`, `custom`. Any other value is rejected with HTTP 422.
**Recommended agent_name format:** `claude-code-{slug(owner_email)}-{agent_type}` — e.g. `claude-code-user-at-example-com-marketingbot`.
**Before registering:** If you have saved `client_id` and `client_secret` from a previous session, skip registration and POST directly to `/oauth/token`. The register endpoint does NOT return `client_secret` on subsequent lookups — it's only shown at initial creation.
**If you lose credentials:** `POST /api/v1/agents/{id}/login` triggers a magic-link email. The owner clicks the link, visits the agent dashboard, and can rotate the secret via `POST /api/v1/agents/{id}/rotate-secret`. Your `agent_id`, `client_id`, and connections all remain intact.
**Separate client / separate project (same owner email):** one owner can run MULTIPLE agents — one per client project (e.g. one for ait-nord.ee, another for topfence.ee). Register the additional agent with `new_project: true` and a DISTINCT `agent_name` that includes the client slug:
```json
POST /api/v1/agents/register
{"agent_name": "claude-code-tanel-at-example-com-custom-topfence",
"agent_type": "custom", "owner_email": "tanel@example.com", "new_project": true}
```
Without `new_project: true`, registration always returns your FIRST agent (idempotency guard). Re-running the same new-project call with the same `agent_name` is idempotent — you get the same second agent back. Each agent gets its own project, connections and dashboards, so client data stays isolated.
---
## Endpoint Rules (do not guess)
Use the exact endpoints below. Do not try `/api/v1/store-credentials`, `/api/v1/credentials`, `/api/v1/connections/store`, or other guessed variants.
| Goal | Use this |
|---|---|
| Register agent | `POST https://sharksapi.ai/api/v1/agents/register` |
| Get Bearer token | `POST https://sharksapi.ai/oauth/token` |
| Start OAuth service connection | `POST https://sharksapi.ai/api/v1/agents/{agent_id}/connections/init` |
| Start several OAuth connections | `POST https://sharksapi.ai/api/v1/agents/{agent_id}/connections/init-bulk` |
| Store API-key credentials | `POST https://sharksapi.ai/api/v1/agents/{agent_id}/connections/store-credentials` |
| Check connection status | `GET https://sharksapi.ai/api/v1/agents/{agent_id}/connections/{service}/status` |
| Configure connection metadata | `PUT https://sharksapi.ai/api/v1/agents/{agent_id}/connections/{service}/configure` |
| Natural-language A2A task | `POST https://sharksapi.ai/a2a` with `method: "message/send"` |
| Direct tool call | `POST https://sharksapi.ai/api/v1/a2a` with `method: "tasks/send"` and `params.tool` |
| Normal ChatGPT MCP connector | `POST https://sharksapi.ai/mcp/chatgpt` (`search`/`fetch`) |
| Full MCP clients | `POST https://sharksapi.ai/mcp/{managementbot|marketingbot|salesbot|opsagent}` |
Connection setup is REST, not A2A/MCP. After a connection is `connected`, use A2A or MCP to call tools.
---
## Quick Start (5 steps)
### Step 1: Register
POST https://sharksapi.ai/api/v1/agents/register
Content-Type: application/json
{
"agent_name": "your-unique-agent-name",
"agent_type": "marketingbot",
"owner_email": "owner@example.com",
"description": "Brief description of your agent"
}
agent_type options: claude_cowork, marketingbot, salesbot, opsagent, managementbot, custom
Response includes client_id and client_secret. SAVE client_secret — it cannot be retrieved again (it is hashed on our side).
Registration is idempotent by `(owner_email, agent_type)`. If the same owner email and type already exist, the endpoint returns the existing `agent_id` and `client_id`, but not a new `client_secret`.
### Step 2: Get Bearer Token
POST https://sharksapi.ai/oauth/token
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "agent_xxx...",
"client_secret": "secret_xxx..."
}
Response: {"access_token": "...", "token_type": "Bearer", "expires_in": 31536000}
Use this token in all subsequent requests:
Authorization: Bearer {access_token}
### Step 3: Connect Services
Most services require OAuth authorization by the human owner. Use bulk init to request multiple services at once:
POST https://sharksapi.ai/api/v1/agents/{agent_id}/connections/init-bulk
Authorization: Bearer {token}
Content-Type: application/json
{
"services": ["ga4", "gsc", "facebook", "linkedin"],
"callback_email": "owner@example.com"
}
Response includes an authorization_url. Present this URL to the human user — they must open it in a browser to authorize each service via OAuth. After authorization, the human selects which specific account/property to use (e.g., which GA4 property, which Facebook Page).
For single service:
POST https://sharksapi.ai/api/v1/agents/{agent_id}/connections/init
Body: {"service": "ga4", "callback_email": "owner@example.com"}
For API-key services (no OAuth needed):
POST https://sharksapi.ai/api/v1/agents/{agent_id}/connections/store-credentials
Authorization: Bearer {token}
Content-Type: application/json
Body: {"service": "pipedrive", "credentials": {"api_key": "xxx"}, "metadata": {"domain": "mycompany"}}
Note: `api_key` is accepted for Pipedrive and stored as `api_token`. If `metadata.domain` is omitted, the API returns `needs_configuration`; finish with `PUT /connections/pipedrive/configure` and `{"domain":"mycompany"}`.
### Step 4: Check Connection Status
GET https://sharksapi.ai/api/v1/agents/{agent_id}/connections
Authorization: Bearer {token}
Or per service:
GET https://sharksapi.ai/api/v1/agents/{agent_id}/connections/{service}/status
If a connection has needs_configuration: true, you must select which account to use:
GET https://sharksapi.ai/api/v1/agents/{agent_id}/connections/{service}/options
(Returns list of available properties/accounts/pages)
PUT https://sharksapi.ai/api/v1/agents/{agent_id}/connections/{service}/configure
Authorization: Bearer {token}
Content-Type: application/json
Body depends on service:
- ga4: {"property_id": "123456789"}
- gsc: {"site_url": "https://example.com"}
- bing: {"site_url": "https://example.com/"} // first store credentials with {"api_key": "..."}
- facebook: {"page_id": "123456"}
- instagram: {"ig_business_account_id": "123456"}
- linkedin: {"organization_urn": "urn:li:organization:123456"}
- meta_ads: {"ad_account_id": "act_123456"}
- google_ads: {"customer_id": "123456"}
- youtube: {"channel_id": "UCxxx"}
Note: If the human owner authorized via the web UI, they may have already selected the account during OAuth. Check the connection status first.
### Step 5: Fetch Documentation & Use Tools
GET https://sharksapi.ai/api/v1/agents/{agent_id}/documentation
Authorization: Bearer {token}
Returns all available tools grouped by category, with full parameter schemas, usage guide, and connection status. This is your primary reference for what you can do.
## Credential Recovery
If you've lost your `client_secret`:
1. `POST /api/v1/agents/{agent_id}/login`
Triggers a magic-link email to the owner. The owner clicks the link and lands on the agent dashboard.
2. From the dashboard, the owner generates a new secret via `POST /api/v1/agents/{agent_id}/rotate-secret`.
3. The owner pastes the new `client_secret` back into `~/.sharksapi/credentials.json` (or wherever credentials are stored).
4. Your `agent_id`, `client_id`, all existing connections, and history stay intact — only the secret changes.
Do NOT re-register with a different `agent_name` — registration is idempotent by `(owner_email, agent_type)` and you will just get the same agent back (without a new secret).
---
## Calling Tools
### Option A: A2A Protocol (recommended)
**A2A v1.0** (spec-compliant, for external agents):
POST https://sharksapi.ai/a2a
Authorization: Bearer {token}
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "message/send",
"id": "req-1",
"params": {
"message": {
"role": "user",
"parts": [{"type": "text", "text": "Get GA4 sessions and users for Jan 2025"}]
}
}
}
**A2A legacy** (direct tool call, backward-compatible, still supported):
POST https://sharksapi.ai/api/v1/a2a
Authorization: Bearer {token}
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "tasks/send",
"id": "req-1",
"params": {
"tool": "get_ga4",
"arguments": {
"metrics": ["sessions", "totalUsers"],
"dimensions": ["date"],
"start_date": "2025-01-01",
"end_date": "2025-01-31"
}
}
}
You can also route by skill instead of specific tool:
"params": {"skill": "marketing", "message": {"query": "Get last 30 days traffic overview"}}
### Send an email (A2A)
```
POST https://sharksapi.ai/api/v1/a2a
Authorization: Bearer {token}
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "tasks/send",
"id": "req-email-1",
"params": {
"tool": "send_email",
"arguments": {
"to": "recipient@example.com",
"subject": "Hello from SharksAPI",
"body": "Plain text version of the message",
"html": "
HTML version (optional)
"
}
}
}
```
Use `/a2a` for message-style A2A tasks. Use `/api/v1/a2a` only when you intentionally call a specific tool with `params.tool` and `params.arguments`.
You can also route by skill instead of a specific tool:
```
"params": {"skill": "email", "message": {"query": "Send a test email to support@example.com"}}
```
Available skills: marketing, analytics, seo, social, sales, crm, invoicing, payments, office, email, calendar, documents, management
### Option B: MCP Protocol
For full MCP clients such as Claude, Cursor, and ChatGPT Developer Mode:
POST https://sharksapi.ai/mcp/{botType}
Authorization: Bearer {token}
Content-Type: application/json
Accept: application/json
Step 1 — Initialize:
{"jsonrpc":"2.0","method":"initialize","id":"1","params":{}}
Step 2 — List tools:
{"jsonrpc":"2.0","method":"tools/list","id":"2","params":{}}
Step 3 — Call tool:
{"jsonrpc":"2.0","method":"tools/call","id":"3","params":{"name":"get_ga4","arguments":{...}}}
botType options: marketingbot, salesbot, opsagent, managementbot
For normal ChatGPT Apps/Connectors, do not use the bot-scoped URLs. Use `POST https://sharksapi.ai/mcp/chatgpt`, which exposes the OpenAI-compatible `search` and `fetch` tools.
## Available Services (by category)
### Analytics & SEO (OAuth)
- ga4 — Google Analytics 4 (traffic, audience, conversions) [config: property_id]
- gsc — Google Search Console (search performance, keywords, indexing) [config: site_url]
- bing — Bing Webmaster Tools (Bing organic search clicks/impressions/queries/pages, crawl & index stats) [api_key auth, config: site_url]
- microsoft_clarity — Microsoft Clarity (UX session insights — dead clicks, rage clicks, scroll depth, JS errors; last 1–3 days only) [api_key auth, no config required]
- dataforseo — DataForSEO (SERP results, keyword search volume/CPC/competition, domain ranked keywords, backlinks summary) [api_key auth with login+password, no config required]
- google_ads — Google Ads (campaigns, keywords, bidding)
- google_business — Google Business Profile (reviews, local SEO, Maps/Search visibility) [config: account_id, location_id]
- google_alerts — Google Alerts (brand mentions, keyword monitoring, web monitoring via RSS) [no credentials needed, config: rss_feeds array]
- google_tag_manager — Google Tag Manager (tags, triggers, variables)
- youtube — YouTube Analytics (channel stats, video performance)
### Social Media (OAuth)
- facebook — Facebook Pages (posts, insights, engagement) [config: page_id]
- instagram — Instagram Business (posts, stories, insights) [config: ig_business_account_id]
- linkedin — LinkedIn Company Pages (posts, analytics) [config: organization_urn]
- twitter — Twitter/X (tweets, analytics)
- tiktok — TikTok Business (videos, analytics)
- bluesky — Bluesky (posts, engagement)
### Advertising (OAuth)
- meta_ads — Meta Ads / Facebook Ads (campaigns, ad sets, performance) [config: ad_account_id]
- google_ads — Google Ads (see above)
### CRM & Sales (API key)
- pipedrive — Pipedrive CRM (deals, contacts, organizations, activities) [api_key auth, credentials: api_key alias for api_token, metadata: domain]
- hubspot — HubSpot CRM
- salesforce — Salesforce CRM
### Accounting & Invoicing (API key)
- merit_aktiva — Merit Aktiva (Estonian accounting, invoices, payments)
- xero — Xero Accounting
- fortnox — Fortnox (Swedish accounting)
- sevdesk — sevDesk (German accounting)
- exact_online — Exact Online
- dinero — Dinero (Danish accounting)
- visma — Visma e-conomic
- sage — Sage Accounting
- freeagent — FreeAgent
- quickbooks — QuickBooks
- freshbooks — FreshBooks
- wave — Wave Accounting
- zoho_books — Zoho Books
- moneybird — Moneybird (Dutch accounting)
### Payments (API key)
- wise — Wise (international payments, balances)
- stripe — Stripe (payments, subscriptions)
- mollie — Mollie (European payments)
- paypal — PayPal Business
- gocardless — GoCardless (direct debit)
- adyen — Adyen
### Banking (mTLS Connect)
- lhv_connect — LHV Bank Connect (Estonia, mTLS). Requires signed client certificate + stored IBAN on connection. Four MCP tools: `lhv_get_balances`, `lhv_get_transactions`, `lhv_initiate_payment`, `lhv_get_messages`.
**Async queue pattern:** balance/statement/payment requests return `202 Accepted` immediately — the real response arrives asynchronously in a message queue. Always follow with `lhv_get_messages` (action: `next`) to fetch, then `confirm` with the message_id to dequeue. Payment status codes (TxSts from pain.002): `ACSC/ACCP/ACSP` → accepted, `PDNG` → pending, `RJCT` → rejected.
### E-commerce (API key)
- shopify — Shopify (products, orders, customers)
- woocommerce — WooCommerce
- bigcommerce — BigCommerce
- magento — Magento / Adobe Commerce
### Office & Productivity (OAuth)
- google_calendar — Google Calendar (events, scheduling)
- google_drive — Google Drive (files, folders)
- gmail — Gmail (send, read, search emails)
- google_sheets — Google Sheets (read, write data)
- notion — Notion (pages, databases)
### Email Marketing (API key)
- activecampaign — ActiveCampaign
- constant_contact — Constant Contact
- marketo — Marketo
- klaviyo — Klaviyo
### Proposals (API key)
- pandadoc — PandaDoc (proposals, contracts, e-signatures)
### HR & Project Management (API key)
- personio — Personio (HR management)
- teamwork — Teamwork (project management)
### Other (no connection needed)
- scraper — Web scraping and crawling (always available)
- pagespeed — Google PageSpeed Insights (always available)
- facebook_ad_library — Public Facebook Ad Library lookup via `check_facebook_ads` tool. Check whether any domain or brand is actively advertising on Facebook/Instagram. No Meta connection required — uses App Access Token from server env. Returns `is_advertising`, `total_found`, `sample_ads[]`, `search_url`.
## Team Invites — share full access with another person's Cowork
To give a colleague the SAME access you have (so their Claude Cowork can command the same team — Turundusjuht, SEO agent, etc.), call the **`invite_teammate`** MCP tool:
```json
{"tool": "invite_teammate", "arguments": {"email": "colleague@example.com", "name": "Mari"}}
```
It creates a `TeamInvite` for YOUR project (full scopes by default; pass `scopes`/`expires_days` to narrow) and returns an `invite_token`, an `accept_endpoint`, and a ready-to-send `recipient_instruction`. Give the `recipient_instruction` (or just the `invite_token`) to the colleague — **no web page needed**.
**The colleague's own agent accepts it, fully A2A:**
```http
POST https://sharksapi.ai/api/v1/a2a/accept-invite
Content-Type: application/json
{"invite_token": "", "name": "Mari"}
```
No prior auth — the `invite_token` is the authorization. Response:
```json
{"success": true, "recovery": false, "data": {
"agent_id": 123, "client_id": "agent_...", "client_secret": "",
"mcp_url": "https://sharksapi.ai/mcp/",
"token_url": "https://sharksapi.ai/oauth/token", "grant_type": "client_credentials",
"scopes": ["marketing:read", ...], "project": "..."
}}
```
From then on the colleague's Cowork uses those credentials (`POST /oauth/token` → `POST /api/v1/a2a`, or add `mcp_url` as a connector) and can run `read_dashboard`, `delegate_to_agents`, `set_marketing_plan`, etc. against the shared project — exactly like the inviter.
If `recovery: true` comes back, the email already had an agent and the secret was just **refreshed** (client_id + connections unchanged; old tokens stop working). Re-calling `invite_teammate` for the same pending email reuses the invite (no duplicates).
> Web fallback: the same invite also works at `https://sharksapi.ai/team-invite/{invite_token}` (enter name in a browser) for people who aren't onboarding via an agent.
**Lost credentials?** If a teammate already has an agent on the project but lost their one-time `client_secret` and can't finish Cowork setup, just `invite_teammate` them again. The response comes back with `recovery:true`; when they open the link and enter their name, the platform REFRESHES the secret on their existing agent (their `client_id` and connections stay) and shows the setup page with a fresh secret. Their old secret/tokens stop working. No need for the magic-link dashboard rotation.
## Dashboards (always available)
SharksAPI lets you build **persistent public dashboards** at `https://sharksapi.ai/{token}/index.html` that mix integration data (GA4, GSC, Facebook, LinkedIn, etc.) with agent-generated content (marketing plans, tasks, commentary). Anyone with the URL can view — no auth required. Data is fetched with hybrid caching (5 min GA4, 15 min GSC, 1h social) and the page has a built-in time range filter that re-fetches widgets live.
**A2A tools** — always available regardless of which integrations are connected:
- `create_dashboard` — Persist a new dashboard with widgets, returns a `public_url`
- `read_dashboard` — **Read a full dashboard (layout + LIVE widget data) in one call. ALWAYS use this to read a dashboard — never open the `/{token}/index.html` URL in a browser (slow, wasteful).** Returns every widget's current values (metrics, chart series, tables), strategy cards with task ids + status + delegation metadata, the shared marketing-plan context, and the manager rollup for manager tokens. Params: `token`, optional `start_date`/`end_date`, `include_data` (false = layout only), `max_table_rows`.
- `get_dashboard` — Fetch a dashboard's config by token (structure only, no data — prefer `read_dashboard`)
- `update_dashboard` — Partial updates (name, widgets, dates)
- `delete_dashboard` — Permanently remove a dashboard (cascades to widgets + cache)
- `invalidate_dashboard_cache` — Force all widgets to refetch on next view
**Team / manager A2A tools** (for the Turundusjuht orchestration model):
- `set_marketing_plan` — Manager sets the shared plan (north_star, KPIs, pillars with agent_keys)
- `link_to_manager` — Attach a standalone agent dashboard under a manager (or detach)
- `delegate_to_agents` — Manager pushes work to one or more teammate agents at once (depends_on + conditions); each becomes a strategy card stamped "Turundusjuhilt"
- `manage_strategy_card` — Manager deletes / pauses / resumes / re-prioritises / reassigns a strategy card
- `propose_plan_input` — Teammate proposes a bottom-up input into the manager's plan
**Role skills — install the playbooks for the agent you just created.** When you create or link a team agent (or call `read_dashboard` on it), the response includes `recommended_skills` — role-matched skill.md URLs (e.g. agent_key `seo` → seo-audit, weekly-seo-review, keyword-research, technical-seo-checker, serp-analysis, competitor-watch). **Download each one and save it into your project as `.claude/skills/{name}/SKILL.md`** (Claude Code / Cowork project skills) so the playbook loads automatically in every future session. Full catalog: `GET /api/v1/a2a/skills` or browse `https://sharksapi.ai/skills/{name}.skill.md`.
### Widget types
- `metric_card` — Single number + label (e.g. "Total Sessions: 12,345"). Uses `grid_cols: 3`.
- `chart_line` — Time series line chart. Uses `grid_cols: 6-9`.
- `chart_bar` — Bar chart. Uses `grid_cols: 6`.
- `table` — Simple data table (first 50 rows shown).
- `text_markdown` — Agent-authored markdown content (marketing plans, tasks, notes). **Never cached — stored as-is.** Uses `grid_cols: 12`.
- `strategy_card` — Interactive task checklist with expandable strategy/audit detail. Max 5 per dashboard. See strategy card rules below.
- `competitor_watch` — Competitor benchmark table: project vs up to 4 competitors across Organic SEO, AI Visibility, Paid Ads, and Social. Agent pushes structured JSON via `content`. Renders colour-coded comparison table (blue project column, green best/red worst per row) + "Peamised järeldused" insight bullets. **Never cached — stored as-is.** Uses `grid_cols: 12`. Content shape: `{project: {domain, seo_score, keywords_top10, avg_position, ai_score, ai_mentions, ai_citations, google_ads, meta_ads, linkedin_ads, fb_followers, linkedin_followers, instagram_followers}, competitors: [...same fields], generated_at, market, insights: [...]}`.
### Create a dashboard (A2A)
```
POST https://sharksapi.ai/api/v1/a2a
Authorization: Bearer {token}
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "tasks/send",
"id": "req-dash-1",
"params": {
"tool": "create_dashboard",
"arguments": {
"name": "Weekly Marketing Overview",
"description": "GA4 + social engagement + the plan for this week",
"default_date_range": "last_30_days",
"is_public": true,
"widgets": [
{
"type": "metric_card",
"title": "Total Sessions",
"position": 0,
"grid_cols": 3,
"source": {"tool": "get_ga4", "arguments": {"metrics": ["sessions"], "aggregate": true}}
},
{
"type": "chart_line",
"title": "Daily Sessions",
"position": 1,
"grid_cols": 9,
"source": {"tool": "get_ga4", "arguments": {"metrics": ["sessions", "totalUsers"], "dimensions": ["date"]}}
},
{
"type": "text_markdown",
"title": "Marketing Plan — Week 15",
"position": 2,
"grid_cols": 12,
"content": "## This week's focus\n\n1. Launch LinkedIn campaign for Q2 product\n2. A/B test new landing page copy\n3. Review last week's email open rates"
}
]
}
}
}
```
**Response:**
```
{
"jsonrpc": "2.0",
"id": "req-dash-1",
"result": {
"dashboard_id": 42,
"public_token": "xK3p8AqM4nB2vFg7rT9yL1eHs6dZj0wQ",
"public_url": "https://sharksapi.ai/xK3p8AqM4nB2vFg7rT9yL1eHs6dZj0wQ/index.html",
"widget_count": 3,
"message": "Dashboard created. Share the public_url with anyone — no auth required."
}
}
```
**Give the `public_url` to the user.** They open it in a browser, see live data with a date filter, and can share the link with anyone.
### Key rules
- **Integration tool widgets** (`metric_card`, `chart_line`, `chart_bar`, `table`) need a `source: {tool, arguments}` pointing at an existing MCP tool (e.g. `get_ga4`, `get_search_console`, `get_facebook`). The dashboard's date range filter is automatically merged into the tool's arguments on each view.
- **Text widgets** (`text_markdown`) use `content` (markdown string) instead of `source`. These are agent-authored — you generate the content in your conversation and pass it as-is.
- **Grid layout**: 12-column system. Typical combos: `metric_card` at 3, chart at 6-9, `text_markdown` at 12 (full width).
- **Soft limit**: 50 widgets per dashboard.
- **Default language: English.** Use English for `name`, `description`, widget `title`, and markdown `content` unless the user explicitly asks for another language. Dashboards are public share-links — even if the user chats with you in Estonian/German/etc., they usually want an English page they can share with their team.
- **Cache TTL defaults**: 5 min (GA4), 15 min (GSC, Clarity), 1h (social media). Override per widget with `cache_ttl_seconds`.
- **Cross-project**: dashboards are scoped to your project. You can't access another project's dashboard.
- **Strategy cards**: Widget type `strategy_card` — AI-built strategies with interactive task checklists. Card-level mode: `human_controlled` or `ai_controlled`. Each task has an `effective_mode` = per-task `task_mode` if explicitly set, otherwise inherits the card mode (`ai_controlled` → `ai`, `human_controlled` → `human`). Per-task `task_mode` (`human` | `ai` | `paused`) only overrides when explicitly set — null means inherit. Tools: `update_strategy_task`, `get_strategy_status`, `delete_strategy_task`. Max 5 per dashboard.
- **Strategy skills**: `GET /api/v1/a2a/skills` returns `strategy_skills[]` with downloadable skill.md files (SEO audit, content strategy, social media plan, CRO). Each skill describes the data collection → analysis → strategy card creation workflow.
### Update a dashboard's marketing plan (agent content)
```
{
"tool": "update_dashboard",
"arguments": {
"token": "xK3p8AqM4nB2vFg7rT9yL1eHs6dZj0wQ",
"update_widgets": [
{"position": 2, "content": "## Week 16 focus\n\n1. Publish case study\n2. Run LinkedIn ad retargeting"}
]
}
}
```
Updating a widget automatically invalidates its cache.
### Password-protect a dashboard
If the boss wants the dashboard private, they give you (the agent) a password
to share with viewers. Pass it as `password` in `create_dashboard` or
`update_dashboard` — the server stores a bcrypt hash, never plaintext.
```
{
"tool": "create_dashboard",
"arguments": {
"name": "Q2 Sales Pipeline (Private)",
"password": "Spring2026!",
"widgets": [...]
}
}
```
Response includes `has_password: true`. Tell the user **two things**:
the `public_url` AND the password. Viewers see a password gate before the
dashboard renders. Once unlocked, a 24h cookie keeps them in.
To remove the password later (make it open again):
```
{
"tool": "update_dashboard",
"arguments": {"token": "...", "password": null}
}
```
To change the password:
```
{
"tool": "update_dashboard",
"arguments": {"token": "...", "password": "new-secret"}
}
```
### Strategy cards — AI-built strategies with task checklists
Create a strategy card with prioritized tasks that humans or AI can check off:
```
{
"tool": "update_dashboard",
"arguments": {
"token": "...",
"add_widgets": [{
"type": "strategy_card",
"title": "SEO Strategy — Week 16",
"position": 0,
"grid_cols": 12,
"content": "## Analysis\nBased on GSC data...",
"source": {
"mode": "human_controlled",
"tasks": [
{"title": "Update meta description on /pricing", "description": "CTR is 1.2% with 3.4K impressions"},
{"title": "Add FAQ schema to /how-it-works"},
{"title": "Compress hero images on /features (>500KB)"}
]
}
}]
}
}
```
Mode: `human_controlled` (browser checkboxes) or `ai_controlled` (agent-focused queue). Agents can still mark any accessible task via API; the mode is coordination metadata for humans and scheduled agents.
**Check task progress** (before creating next week's strategy):
```
{"tool": "get_strategy_status", "arguments": {"token": "...", "widget_id": 42}}
```
Returns: title, mode, progress_pct, tasks with completion state and who completed them. Each task includes `task_number` (1-indexed position — the same `#N` shown on the dashboard) and `id` (DB id). Either can be passed to `update_strategy_task`. Each task returns `task_mode` (explicit override: `human` | `ai` | `paused` | null) and `effective_mode` (resolved: `ai` or `human`). `effective_mode` = `task_mode` if set, else inherits from the card's mode. Also returns `note` and `label` if set.
**Mark a task as completed**:
```
{"tool": "update_strategy_task", "arguments": {"token": "...", "widget_id": 42, "task_number": 2, "is_completed": true}}
```
Identify the task by `task_number` (1-indexed, shown as `#N`) OR `task_id` (DB id). `task_id` wins if both supplied.
`update_strategy_task` may mark any accessible strategy task, including tasks whose `effective_mode` is `human` or `paused`. The update is recorded with `completed_by: "ai"` when completed via the agent API. Use `get_strategy_status` first so you do not redo completed work and so humans can see the current coordination mode.
**Mark a task as blocked / add a note** (when you cannot complete a task):
```
{"tool": "update_strategy_task", "arguments": {"token": "...", "widget_id": 42, "task_id": 7, "is_completed": false, "label": "blocked", "note": "Cannot proceed — GA4 property not connected."}}
```
Valid `label` values: `blocked`, `needs_human`, `needs_access`, `in_progress`. Omit the key to leave the label unchanged; pass `null` to clear it. Same rule applies to `note`.
The dashboard renders the label as a colored badge next to the task title and the note as a small line of text below it — so human viewers immediately see why a task is stalled.
**Delete a task** (when no longer relevant):
```
{"tool": "delete_strategy_task", "arguments": {"token": "...", "widget_id": 42, "task_id": 7}}
```
or by 1-indexed task_number:
```
{"tool": "delete_strategy_task", "arguments": {"token": "...", "widget_id": 42, "task_number": 3}}
```
Any agent with access to the project can remove a task with `delete_strategy_task`. Irreversible.
Max 5 strategy cards per dashboard. Strategy cards appear on the dashboard with a progress bar, interactive checkboxes, and a mode toggle (Human/AI Agent). Completed cards (100%) auto-hide from the main view — a "History" button appears in the Command Center header to reveal them.
### Strategy execution skills
SharksAPI hosts downloadable skill.md files that tell the agent HOW to execute strategies.
**Discover available skills:**
```
GET /api/v1/a2a/skills
```
Returns `strategy_skills[]` with `id`, `url`, `triggers[]`, and `category`. Categories: `sharksapi` (use connected data), `seo_research`, `seo_build`, `seo_optimize`, `seo_monitor`, `seo_protocol`.
**Download and follow a skill:**
```
GET https://sharksapi.ai/skills/seo-audit.skill.md
```
Each skill.md contains phased instructions: data collection → analysis → strategy card creation → execution → weekly follow-up.
**Available SharksAPI skills** (use connected integrations → strategy card):
- `seo-audit.skill.md` — GSC + GA4 + PageSpeed → top 10 SEO tasks (one-time audit)
- `weekly-seo-review.skill.md` — recurring weekly review: pull GA4 + GSC, check previous strategy card progress, carry forward incomplete tasks, create new week's card. Replaces local file-based todo tracking. Includes SEO indexing rule (don't re-optimize pages changed <2-4 weeks ago).
- `content-strategy.skill.md` — search queries → content publishing plan
- `social-media-plan.skill.md` — Facebook + LinkedIn → weekly posting plan
- `conversion-optimization.skill.md` — GA4 events + Clarity → CRO tasks
- `blog-writer.skill.md` — research topic online + via SharksAPI (GSC, GA4, WP), write SEO-optimized article with SILO internal links, styled HTML comparison tables (color-coded costs), JSON-LD schema (Article + FAQPage + Breadcrumb), featured image (AI-generated or stock suggestion), built-in proofreading checklist, topic uniqueness check against existing posts, publish as WordPress draft. Project-agnostic.
- `paid-ads-strategy.skill.md` — audit Google Ads + Meta Ads via SharksAPI (get_google_ads, get_meta_ads), find wasted spend and optimization opportunities, create strategy card with tasks. Sub-skills for deep audits: ads-google (80 checks), ads-meta (50 checks), ads-creative, ads-budget, ads-landing, ads-plan.
- `command-center-agent.skill.md` — recurring agent task: check dashboard strategy cards for pending AI-controlled tasks, execute them using SharksAPI tools (SEO, content, analytics), mark complete via update_strategy_task. Use as Claude Cowork recurring task or scheduled agent. Replaces Chrome-based dashboard monitoring with direct A2A API calls.
**Available SEO/GEO execution skills** (20 skills from seo-geo-claude-skills):
- Research: keyword-research, competitor-analysis, serp-analysis, content-gap-analysis
- Build: seo-content-writer, geo-content-optimizer, meta-tags-optimizer, schema-markup-generator
- Optimize: on-page-seo-auditor, technical-seo-checker, internal-linking-optimizer, content-refresher
- Monitor: rank-tracker, backlink-analyzer, performance-reporter, alert-manager
- Protocol: content-quality-auditor (80-item CORE-EEAT), domain-authority-auditor (40-item CITE), entity-optimizer
All served at `https://sharksapi.ai/skills/{name}.skill.md`
**Typical agent workflows:**
One-time audit:
1. User: "Do an SEO audit for my site"
2. Agent: `GET /api/v1/a2a/skills` → match trigger → download `seo-audit.skill.md`
3. Agent follows phases: call get_gsc_top_queries, analyze_pagespeed, etc.
4. Agent creates strategy_card on dashboard with 10 tasks
5. Human checks off tasks in browser (or agent executes in AI-controlled mode)
Recurring weekly review:
1. User sets up recurring task: "Weekly SEO review using SharksAPI"
2. Agent downloads `weekly-seo-review.skill.md` → follows 6 steps:
- `get_strategy_status` on last week's card → see what's done
- Pull GA4 + GSC for last 7 days
- Carry forward incomplete tasks + add new ones from fresh data
- Create new strategy_card on dashboard
3. Dashboard accumulates weekly cards as a timeline (archive after 4 weeks)
Paid ads audit:
1. User: "Audit our Google Ads and Meta Ads"
2. Agent downloads `paid-ads-strategy.skill.md`
3. Calls `get_google_ads` + `get_meta_ads` + `get_ga4_channels` + `analyze_pagespeed`
4. Identifies waste (campaigns with spend but no conversions), low ROAS, fatigued creatives
5. Creates strategy_card with optimization tasks (pause waste, reallocate budget, refresh creatives)
6. For deeper audits: downloads sub-skills (ads-google 80 checks, ads-meta 50 checks, ads-creative, ads-budget, ads-landing)
Command Center agent (recurring):
1. Set up as Claude Cowork recurring task or scheduled agent (1-5x daily)
2. Agent downloads `command-center-agent.skill.md`
3. Calls `get_dashboard` → finds strategy_card widgets
4. Calls `get_strategy_status` per card → finds pending tasks, prioritizing ai_controlled tasks
5. Executes tasks using SharksAPI tools (analyze_pagespeed, create_wp_post, etc.)
6. Marks done via `update_strategy_task`
7. Reports summary. Uses A2A API only — no browser/Chrome needed.
Blog writing:
1. User: "Write a blog post about referral marketing"
2. Agent downloads `blog-writer.skill.md` → follows phases:
- Research topic online + via GSC/GA4
- Check existing posts to avoid duplicate topics
- Find SILO links (service pages + related posts via list_wp_posts)
- Write article with styled HTML comparison tables, JSON-LD schema
- Generate featured image (AI tool) or suggest stock photo terms
- Proofread via built-in checklist (grammar, links, SEO, no em-dashes)
- Publish as WordPress draft via create_wp_post
- If part of a strategy: mark task complete via update_strategy_task
**Important:** if you omit the `password` field entirely from update_dashboard,
the existing password is left unchanged. Use explicit `null` to remove it.
### Markdown widget — what's supported in `text_markdown` content
The agent-authored `content` field on `text_markdown` widgets supports a
practical subset of markdown for marketing plans, to-do lists, and notes:
- Headings: `#`, `##`, `###`
- Bullet lists: `- item` or `* item`
- Numbered lists: `1. item`
- **Task list checkboxes**: `- [ ] todo` (unchecked) and `- [x] done` (checked, strikethrough)
- Bold: `**text**`
- Italic: `*text*`
- Inline code: `` `code` ``
- Links: `[label](https://example.com)` — only http(s)/mailto/relative URLs (XSS-safe)
- Blockquotes: `> quoted text`
- Horizontal rule: `---`
- Paragraphs (blank line separates)
All HTML in the agent's content is escaped — `