> ## Documentation Index
> Fetch the complete documentation index at: https://www.citedy.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Complete Agent API endpoint reference — methods, paths, auth, costs, and examples

# Agent Platform — API Reference

All endpoints require:

```
Authorization: Bearer <AGENT_API_KEY>
Content-Type: application/json
```

Base URL: `https://www.citedy.com`

Credit value: 1 credit = \$0.01 USD

***

## MCP v1 Exposure Policy (Public)

This file documents the full Agent API.
Public MCP v1 intentionally exposes a smaller, outcome-first subset:

* `GET /api/agent/health`
* `GET /api/agent/status`
* `GET /api/agent/settings`
* `GET /api/agent/schedule/gaps`
* `GET /api/agent/webhooks/deliveries`
* `POST /api/agent/products`
* `GET /api/agent/products`
* `DELETE /api/agent/products/[id]`
* `POST /api/agent/products/search`
* `POST /api/agent/shorts`
* `GET /api/agent/shorts/[id]`
* `POST /api/agent/shorts/script`
* `POST /api/agent/shorts/avatar`
* `POST /api/agent/shorts/merge`

Not in public MCP v1 (still available in Agent API): `PUT /api/agent/settings`, `GET /api/agent/schedule/suggest`.

***

## Account & Auth

### Register Agent

```
POST /api/agent/register
Auth: none (public)
Cost: 0 credits
```

Request:

```json theme={null}
{
  "email": "user@example.com",
  "blogHandle": "myblog"
}
```

Response:

```json theme={null}
{
  "apiKey": "cty_...",
  "tenantId": "uuid",
  "domain": "myblog.citedy.com"
}
```

***

### Get Agent Info

```
GET /api/agent/me
Auth: Bearer
Cost: 0 credits
```

Response:

```json theme={null}
{
  "tenantId": "uuid",
  "domain": "myblog.citedy.com",
  "balance": 247,
  "plan": "credits"
}
```

***

### Health Check (Infrastructure)

```
GET /api/agent/health
Auth: Bearer
Cost: 0 credits
```

Response:

```json theme={null}
{
  "status": "healthy",
  "checks": {
    "redis": true,
    "supabase": true
  }
}
```

***

### Operational Status Snapshot

```text theme={null}
GET /api/agent/status
Auth: Bearer
Cost: 0 credits
```

Response (shape excerpt):

```json theme={null}
{
  "summary": {
    "operational_status": "attention",
    "ready_to_create": true,
    "ready_to_publish": false
  },
  "billing": {
    "credits_available": 100,
    "status": "low",
    "topup_url": "https://www.citedy.com/dashboard/billing"
  },
  "social": {
    "connected_count": 0,
    "connect_url": "https://www.citedy.com/dashboard/settings?section=account&tab=integrations"
  },
  "knowledge": {
    "documents_count": 0,
    "add_documents_url": "https://www.citedy.com/dashboard/settings?section=blog&tab=knowledge"
  },
  "schedule": {
    "scheduled_7d": 0,
    "calendar_url": "https://www.citedy.com/dashboard/calendar"
  },
  "actions": [
    {
      "severity": "critical",
      "title": "No social accounts connected",
      "url": "https://www.citedy.com/dashboard/settings?section=account&tab=integrations"
    }
  ]
}
```

***

### Rotate API Key

```
POST /api/agent/rotate-key
Auth: Bearer
Cost: 0 credits
```

Response:

```json theme={null}
{ "apiKey": "cty_new_..." }
```

***

## Settings

### Get Agent Settings

```
GET /api/agent/settings
Auth: Bearer
Cost: 0 credits
```

Response: full `AgentSettings` object (see [SETTINGS.md](./SETTINGS.md))

***

### Update Agent Settings

```
PUT /api/agent/settings
Auth: Bearer
Cost: 0 credits
```

API availability: yes.
MCP v1 public exposure: advanced/deferred (web-first by default).

Request: partial `AgentSettings` (any fields, all optional):

```json theme={null}
{
  "trustLevel": "show_preview",
  "imageStylePreset": "tech",
  "contentTone": "casual"
}
```

Response: updated `AgentSettings`

***

### Switch Image Style

```
PUT /api/agent/image-style
Auth: Bearer
Cost: 0 credits
```

Request:

```json theme={null}
{ "style": "bold" }
```

Values: `minimal` | `tech` | `bold`

***

## Content Creation

### Create Micro-Post

```
POST /api/agent/post
Auth: Bearer
Cost: 2-4 credits
```

Creates a social-only post (does not go to blog). Generates social adaptation stubs per platform.

Request:

```json theme={null}
{
  "topic": "AI agents changing how we code",
  "platforms": ["x_article", "linkedin"],
  "tone": "casual",
  "imageStyle": "tech",
  "withImage": true
}
```

Response:

```json theme={null}
{
  "postId": "uuid",
  "adaptations": [
    {
      "platform": "x_article",
      "content": "AI agents are...",
      "characterCount": 276
    },
    {
      "platform": "linkedin",
      "content": "The way we build software is changing...",
      "characterCount": 892
    }
  ],
  "imageUrl": "https://download.citedy.com/images/...",
  "creditsCharged": 4
}
```

***

### Generate Blog Article (Autopilot)

```
POST /api/agent/autopilot
Auth: Bearer
Cost: 4-48 credits (by size + intelligence)
```

Request:

```json theme={null}
{
  "topic": "Getting started with MCP",
  "size": "standard",
  "withIntelligence": true
}
```

Sizes: `mini` (7 credits) | `standard` (12 credits) | `full` (25 credits) | `pillar` (40 credits)
Plus CI intelligence: +8 credits

***

### Create Social Adaptation

```
POST /api/agent/adapt
Auth: Bearer
Cost: 0-2 credits
```

Adapt an existing article for specific social platforms.

Request:

```json theme={null}
{
  "articleId": "uuid",
  "platforms": ["linkedin", "x_thread"],
  "tone": "professional"
}
```

***

## Publishing & Scheduling

### Publish Content

```
POST /api/agent/publish
Auth: Bearer
Cost: 0 credits
```

Request for immediate publish:

```json theme={null}
{
  "contentId": "uuid",
  "action": "now",
  "platforms": ["x_article", "linkedin"]
}
```

Request for scheduled publish:

```json theme={null}
{
  "contentId": "uuid",
  "action": "schedule",
  "scheduledAt": "2026-03-01T09:00:00-05:00",
  "platforms": ["x_article", "linkedin"]
}
```

Request to cancel:

```json theme={null}
{
  "contentId": "uuid",
  "action": "cancel"
}
```

Response:

```json theme={null}
{
  "status": "scheduled",
  "scheduledAt": "2026-03-01T09:00:00-05:00",
  "platforms": ["x_article", "linkedin"],
  "qstashMessageId": "msg_..."
}
```

***

### Get Schedule (Timeline)

```
GET /api/agent/schedule
Auth: Bearer
Cost: 0 credits
```

Query params: `from` (ISO date), `to` (ISO date)

Response:

```json theme={null}
{
  "items": [
    {
      "id": "uuid",
      "title": "AI agents post",
      "type": "post",
      "status": "scheduled",
      "scheduledAt": "2026-03-01T09:00:00-05:00",
      "platforms": ["x_article", "linkedin"]
    }
  ]
}
```

***

### Get Schedule Gaps

```
GET /api/agent/schedule/gaps
Auth: Bearer
Cost: 0 credits
```

Returns days within the next 7 days that have fewer posts than `postsPerDay` setting.

Response:

```json theme={null}
{
  "gaps": ["2026-03-02", "2026-03-04"],
  "target": 2
}
```

***

### Get Suggested Posting Slots

```
GET /api/agent/schedule/suggest
Auth: Bearer
Cost: 0 credits
```

API availability: yes.
MCP v1 public exposure: advanced/deferred.

Returns optimal times for tenant's timezone based on best-practice engagement windows.

Response:

```json theme={null}
{
  "timezone": "America/New_York",
  "slots": ["09:00", "17:00"],
  "rationale": "Peak engagement for US Eastern audience"
}
```

***

## Trend Scanning

### Scan Trends

```
POST /api/agent/scan
Auth: Bearer
Cost: 2 / 4 / 6 / 8 credits (fast / deep / ultra / ultra+)
```

Request:

```json theme={null}
{
  "query": "AI coding agents 2026",
  "mode": "deep",
  "limit": 10
}
```

Mode values: `fast` | `deep` | `ultra` | `ultra+`
Default mode derived from `scanSources` in Agent Settings if not specified.
Max limit: 30

Response:

```json theme={null}
{
  "results": [
    {
      "title": "Claude Code surpasses GitHub Copilot in adoption",
      "summary": "New data shows...",
      "url": "https://x.com/...",
      "source": "x",
      "relevance": 0.94,
      "knowledgeMatch": {
        "content": "Our MCP integration feature...",
        "similarity": 0.87,
        "document_id": "uuid"
      }
    }
  ],
  "mode": "deep",
  "creditsCharged": 4,
  "hnFailed": false
}
```

`knowledgeMatch` is only present when tenant has product knowledge documents uploaded and a match is found.

***

## Product Knowledge Base

### Upload Document

```
POST /api/agent/products
Auth: Bearer
Cost: 1 credit (text) / 2 credits (URL)
```

Accepts text content or a URL. Content is chunked, embedded (Gemini), and stored in pgvector.

Request (text):

```json theme={null}
{
  "content": "Our product has an MCP integration that...",
  "title": "MCP Integration Feature",
  "type": "text"
}
```

Request (URL):

```json theme={null}
{
  "url": "https://docs.yourproduct.com/mcp",
  "title": "MCP Docs",
  "type": "url"
}
```

Response:

```json theme={null}
{
  "documentId": "uuid",
  "chunks": 12,
  "creditsCharged": 1
}
```

***

### List Documents

```
GET /api/agent/products
Auth: Bearer
Cost: 0 credits
```

Response:

```json theme={null}
{
  "documents": [
    {
      "id": "uuid",
      "title": "MCP Integration Feature",
      "createdAt": "2026-02-20T10:00:00Z",
      "chunks": 12,
      "type": "text"
    }
  ],
  "total": 1
}
```

***

### Delete Document

```
DELETE /api/agent/products/[id]
Auth: Bearer
Cost: 0 credits
```

Deletes document, all chunks, and Redis cache. Tenant ownership verified before delete.

Response: `204 No Content`

***

### Search Knowledge Base

```
POST /api/agent/products/search
Auth: Bearer
Cost: 0 credits
```

Request:

```json theme={null}
{
  "query": "MCP integration",
  "limit": 5
}
```

Response:

```json theme={null}
{
  "results": [
    {
      "content": "Our MCP integration allows agents to...",
      "similarity": 0.92,
      "documentId": "uuid",
      "documentTitle": "MCP Integration Feature"
    }
  ]
}
```

***

## Video (Shorts)

See [SHORTS-PIPELINE.md](./SHORTS-PIPELINE.md) for full pipeline documentation.

### Generate Video

```
POST /api/agent/shorts
Auth: Bearer
Cost: 60 / 130 / 185 credits (5s / 10s / 15s)
```

Fire-and-forget. Returns `generationId` immediately; poll for status.

Request:

```json theme={null}
{
  "prompt": "An enthusiastic tech founder presenting MCP integration",
  "avatarUrl": "https://download.citedy.com/avatars/...",
  "duration": 15,
  "aspectRatio": "9:16",
  "speech_text": "AI agents can now control your entire workflow...",
  "resolution": "1280x720"
}
```

Response:

```json theme={null}
{
  "generationId": "uuid",
  "status": "generating",
  "pollUrl": "/api/agent/shorts/uuid"
}
```

***

### Poll Video Status

```
GET /api/agent/shorts/[id]
Auth: Bearer
Cost: 0 credits
```

Response (generating):

```json theme={null}
{ "status": "generating", "generationId": "uuid" }
```

Response (completed):

```json theme={null}
{
  "status": "completed",
  "generationId": "uuid",
  "videoUrl": "https://download.citedy.com/shorts/tenant/uuid.mp4",
  "subtitlesApplied": true,
  "subtitleWarning": null
}
```

Response (failed):

```json theme={null}
{
  "status": "failed",
  "generationId": "uuid",
  "error": "Both video providers failed after retries"
}
```

***

### Generate Script

```
POST /api/agent/shorts/script
Auth: Bearer
Cost: 1 credit
```

API availability: yes.
MCP v1 public exposure: yes.

Request:

```json theme={null}
{
  "topic": "MCP integration for AI coding agents",
  "style": "hook",
  "product_id": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
  "duration": "short",
  "language": "en"
}
```

Fields:

* `topic`: string (required)
* `style`: `hook` | `educational` | `cta` (default: `hook`)
* `product_id`: UUID (optional) — link to a product knowledge document
* `duration`: `short` | `long` (optional, default: `short`)
* `language`: language code (optional, default: `"en"`)

Response:

```json theme={null}
{
  "speechText": "Most developers don't know this yet...",
  "hookLine": "Most developers don't know this yet",
  "subtitlePhrases": [
    { "text": "Most developers" },
    { "text": "don't know this" },
    { "text": "yet..." }
  ],
  "creditsCharged": 1
}
```

***

### Generate Avatar

```
POST /api/agent/shorts/avatar
Auth: Bearer
Cost: 3 credits
```

API availability: yes.
MCP v1 public exposure: yes.

Request:

```json theme={null}
{
  "gender": "male",
  "origin": "european",
  "age_range": "26-35",
  "type": "tech_founder",
  "location": "coffee_shop"
}
```

Fields:

* `gender`: `male` | `female`
* `origin`: `european` | `asian` | `african` | `latin` | `middle_eastern` | `south_asian`
* `age_range`: `18-25` | `26-35` | `36-50` (default: `26-35`)
* `type`: `tech_founder` | `vibe_coder` | `student` | `executive` (default: `tech_founder`)
* `location`: `coffee_shop` | `dev_cave` | `street` | `car` | `home_office` | `podcast_studio` | `glass_office` | `rooftop` | `bedroom` | `park` | `gym` (default: `coffee_shop`)

Response:

```json theme={null}
{
  "avatarUrl": "https://download.citedy.com/avatars/tenant/uuid.png",
  "provider": "gemini",
  "creditsCharged": 3
}
```

Provider chain: `gemini` → `openai-high` → `bytedance` → `zai`

***

### Merge Video Segments

```
POST /api/agent/shorts/merge
Auth: Bearer
Cost: 5 credits
```

API availability: yes.
MCP v1 public exposure: yes.

Merges 2 or more video segments, trims silence, applies audio crossfade, renders subtitles.

Request:

```json theme={null}
{
  "videoUrls": [
    "https://download.citedy.com/shorts/.../part1.mp4",
    "https://download.citedy.com/shorts/.../part2.mp4"
  ],
  "subtitlePhrases": [{ "text": "First phrase" }, { "text": "Second phrase" }]
}
```

Response:

```json theme={null}
{
  "mergedVideoUrl": "https://download.citedy.com/shorts/tenant/merged-uuid.mp4",
  "subtitlesApplied": true,
  "creditsCharged": 5
}
```

***

## Intelligence & Research

### Content Gaps — Generate

```text theme={null}
POST /api/agent/gaps/generate
Auth: Bearer
Cost: 40 credits
```

Request:

```json theme={null}
{
  "competitor_urls": ["https://competitor-a.com", "https://competitor-b.com"],
  "favorite_id": "00000000-0000-0000-0000-000000000000"
}
```

Fields:

* `competitor_urls`: `string[]` (1-5 URLs, validated for SSRF) — required
* `favorite_id`: UUID (optional, since 2026-05-04) — scope gaps to a specific `ai_favorites` row (product/identity). When present:
  * owner-checked against `ai_favorites WHERE id=? AND tenant_id=?` **before** charge — cross-tenant ID returns `403` with no credits used
  * analysis domain is overridden to `ai_favorites.domain` instead of the legacy `${blog_handle}.citedy.com`
  * each persisted `ai_content_gaps` row is tagged with this `favorite_id`

Response:

```json theme={null}
{
  "gaps_found": 5,
  "gaps": [
    {
      "title": "AI agents for non-technical PMs",
      "gap_type": "topic",
      "priority": "high",
      "opportunity_score": 87,
      "description": "Competitors cover this; you don't. Match their angle but lead with checklist."
    }
  ],
  "credits_used": 40
}
```

Status codes: `200` / `400` (validation, no blog/favorite) / `401` / `402` (insufficient credits) / `403` (cross-tenant `favorite_id`) / `429` (10/hour rate limit) / `500`.

***

### Content Gaps — List

```text theme={null}
GET /api/agent/gaps?favorite_id=<uuid>&limit=<1-100>
Auth: Bearer
Cost: 0 credits
```

Query params (all optional):

* `favorite_id`: UUID — scope to a specific favorite. Hybrid filter: returns rows tagged with this favorite **or** legacy NULL rows whose `domain` matches the favorite's domain (so pre-favorite gaps are not lost from the view).
* `limit`: integer 1-100 (default 100).

Response:

```json theme={null}
{
  "gaps": [
    {
      "id": "uuid",
      "title": "...",
      "gap_type": "topic",
      "opportunity_score": 87,
      "priority": "high",
      "status": "pending",
      "description": "...",
      "favorite_id": "00000000-0000-0000-0000-000000000000",
      "created_at": "2026-05-04T12:00:00Z"
    }
  ],
  "total_gaps": 1,
  "credits_used": 0
}
```

Status codes: `200` / `400` (bad query params) / `401` / `403` (cross-tenant `favorite_id`) / `429` / `500`.

***

### Competitor Discovery

```
POST /api/agent/competitors/discover
Auth: Bearer
Cost: 20 credits
```

***

### Competitor Scout

```
POST /api/agent/competitors/scout
Auth: Bearer
Cost: 25 credits (fast) / 50 credits (ultimate)
```

***

### X Intent Scout

```
POST /api/agent/scout/x
GET  /api/agent/scout/x/[runId]
Auth: Bearer
Cost: 35 / 70 credits (fast / ultimate)
```

***

### Reddit Intent Scout

```
POST /api/agent/scout/reddit
GET  /api/agent/scout/reddit/[runId]
Auth: Bearer
Cost: 30 credits
```

***

## Content Ingestion

### Ingest URL / Video

```
POST /api/agent/ingest
Auth: Bearer
Cost: 1-55 credits (by content type and duration)
```

Request:

```json theme={null}
{
  "url": "https://youtube.com/watch?v=...",
  "type": "youtube_video"
}
```

Types and costs:

* `web_article`: 1 credit
* `pdf_document`: 2 credits
* `youtube_video`: 5-55 credits (by duration)
* `audio_file`: 3-30 credits (by duration)

***

### Get Ingested Content

```
GET  /api/agent/ingest/[id]
GET  /api/agent/ingest/[id]/content
Auth: Bearer
Cost: 0 credits
```

***

## Lead Magnets

### Generate Lead Magnet

```
POST /api/agent/lead-magnets
Auth: Bearer
Cost: 30 credits (text only) / 100 credits (with images)
```

Types: `checklist` | `swipe_file` | `framework`

***

### Get Lead Magnet

```
GET /api/agent/lead-magnets/[id]
Auth: Bearer
Cost: 0 credits
```

***

## Personas

### List Personas

```
GET  /api/agent/personas
Auth: Bearer
Cost: 0 credits
```

***

## Webhooks

### Manage Webhooks

```
GET    /api/agent/webhooks
POST   /api/agent/webhooks
DELETE /api/agent/webhooks/[id]
GET    /api/agent/webhooks/deliveries
Auth: Bearer
Cost: 0 credits
```

Webhook events: `post.published`, `post.scheduled`, `video.completed`, `video.failed`, `scan.completed`

***

## Error Responses

All errors follow:

```json theme={null}
{
  "error": "Description of the error",
  "code": "ERROR_CODE"
}
```

Common codes:

| HTTP | Code                  | Meaning                                |
| ---- | --------------------- | -------------------------------------- |
| 400  | VALIDATION\_ERROR     | Invalid request body                   |
| 401  | UNAUTHORIZED          | Missing or invalid API key             |
| 402  | INSUFFICIENT\_CREDITS | Not enough credits                     |
| 403  | FORBIDDEN             | Resource belongs to another tenant     |
| 429  | RATE\_LIMITED         | Too many requests                      |
| 503  | SERVICE\_UNAVAILABLE  | Redis or external provider unavailable |

Insufficient credits response also includes:

```json theme={null}
{
  "error": "Insufficient credits",
  "required": 60,
  "available": 10,
  "topUpUrl": "https://www.citedy.com/dashboard/billing"
}
```
