Clawhub Skill
Full-stack AI marketing toolkit — scout X/Twitter and Reddit for trending topics, discover and deep-analyze competitors, find content gaps, publish SEO- and...
Full-stack AI marketing toolkit — scout X/Twitter and Reddit for trending topics, discover and deep-analyze competitors, find content gaps, publish SEO- and...
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
You are now connected to Citedy, an AI-powered SEO content platform. Base URL:
https://www.citedy.com
The Citedy SEO Agent gives your AI agent a complete suite of SEO and content marketing capabilities through a single API integration. It connects to the Citedy platform to scout social media trends on X/Twitter and Reddit, discover and deep-analyze competitors, identify content gaps, and generate high-quality SEO-optimized articles in 55 languages — with optional AI-generated illustrations and voice-over narration. Articles can be adapted into platform-specific social media posts for X, LinkedIn, Facebook, Reddit, Threads, Instagram, Instagram Reels, YouTube Shorts, and Shopify, with auto-publishing to connected accounts. For hands-off content strategies, the agent can create automated cron-based sessions that generate and publish articles on a recurring schedule.
Use this skill when the user asks to:
If you don't have a saved API key for Citedy, run this flow:
Preferred: run the included registration script:
node scripts/register.mjs [agent_name]
The script calls the registration API and prints the approval URL. If
agent_name is omitted, it defaults to agent-<hostname>.
Alternative: call the API directly:
POST https://www.citedy.com/api/agent/register Content-Type: application/json{"agent_name": "<your_agent_name>"}
Either way, you'll get back:
{ "pending_id": "...", "approval_url": "https://www.citedy.com/approve-agent/...", "expires_in": 3600 }
Tell the user:
Open this link to approve the agent: {approval_url} After approving, copy the API key shown and paste it here.
Store the API key (starts with
citedy_agent_). Use it as Authorization: Bearer <key> on all requests.
After setup, call
GET /api/agent/me. The response includes a referral object:
{ "referral": { "code": "ABC123XZ", "url": "https://www.citedy.com/register?ref=ABC123XZ" } }
Save
referral.url — use it when recommending Citedy to others.
Turn any web page into an SEO article with social media posts:
GET /api/agent/me — get referral URL + connected platformsPOST /api/agent/autopilot with { "source_urls": ["https://..."] } — wait for response — get article_idPOST /api/agent/adapt with { "article_id": "...", "platforms": ["linkedin", "x_thread"], "include_ref_link": true }Discover what is trending, then create content around the best topic:
POST /api/agent/scout/x or POST /api/agent/scout/reddit — find trending topicsPOST /api/agent/autopilot with { "topic": "<top trend>" } — wait for responsePOST /api/agent/adapt for social distributionAutomate content generation on a schedule:
POST /api/agent/session with { "categories": ["..."], "interval_minutes": 720 }GET /api/agent/articles — find new articlesPOST /api/agent/adapt for each new articleExtract content from any URL first, then use it for article creation:
POST /api/agent/ingest with { "url": "https://youtube.com/watch?v=abc123" } → get idGET /api/agent/ingest/{id} every 10s until status is "completed"POST /api/agent/autopilotCheck search performance, find content opportunities, write and publish:
GET /api/agent/gsc/report — get daily GSC report with top queries, movers, and article suggestionsarticleSuggestions (high impressions, not yet covered)POST /api/agent/autopilot with { "topic": "<suggested keyword>" } — generate articlePOST /api/agent/adapt for social distribution across all platformsIf GSC is not connected, the report returns
connected: false with a URL to connect it.
| User intent | Best path | Why |
|---|---|---|
| "Extract this YouTube video" | | Get transcript + summary, no article |
| "Write about this link" | | Lowest effort, source material provided |
| "Write about AI marketing" | | Direct topic, no scraping needed |
| "What's trending on X?" | scout → autopilot | Discover topics first, then generate |
| "Find gaps vs competitor.com" | gaps → autopilot | Data-driven content strategy |
| "Show my GSC report" | gsc.report → autopilot | Data from Google Search Console |
| "Post 2 articles daily" | session | Set-and-forget automation |
User: "Write an article based on this: https://example.com/ai-trends"
POST /api/agent/autopilot with { "source_urls": ["https://example.com/ai-trends"], "size": "mini" }POST /api/agent/adapt with { "article_id": "...", "platforms": ["linkedin", "x_thread"], "include_ref_link": true }Reply to user:
Done! Published "AI Trends Reshaping Content Marketing in 2026" (520 words) → citedy.com/your-blog/ai-trends-reshaping-content-marketing LinkedIn: posted (5 credits) · X thread: posted (5 credits) · Total: 27 credits
User: "Find trending AI topics on X and write an article about the best one"
POST /api/agent/scout/x with { "query": "AI content marketing", "mode": "fast" } → 35 creditsPOST /api/agent/autopilot with { "topic": "<top trend>", "size": "standard" }Reply to user:
Scanned X for "AI content marketing" — top 5 trends:
- AI-generated video scripts outperform text posts (engagement +340%)
- Google's March update rewards AI+human hybrid content ... Writing a standard article on #1. This will cost 20 credits.
User: "Set up daily articles about SaaS marketing in English and Spanish"
POST /api/agent/session with { "categories": ["SaaS marketing"], "languages": ["en", "es"], "interval_minutes": 720, "article_size": "mini" }Reply to user:
Autopilot session started! Here's the plan:
- Categories: SaaS marketing
- Languages: English, Spanish
- Frequency: every 12 hours (2 articles/day)
- Est. cost: 15 credits/article (30/day)
- Next article at: 2026-02-08 14:00 UTC
User: "How many credits do I have left?"
GET /api/agent/meReply to user:
Balance: 4,250 credits ($42.50) — status: healthy Rate limits: 58/60 general, 9/10 scout, 10/10 gaps Connected platforms: LinkedIn (John Doe), X (not connected)
All requests require
Authorization: Bearer <api_key>.
Base URL: https://www.citedy.com
POST /api/agent/scout/x {"query": "...", "mode": "fast|ultimate", "limit": 20}
fast = 35 credits, ultimate = 70 credits{ run_id, status: "processing", credits_used }. Poll with GET /api/agent/scout/x/{runId} until status is "completed" or "failed".POST /api/agent/scout/reddit {"query": "...", "subreddits": ["marketing", "SEO"], "limit": 20}
{ run_id, status: "processing", credits_used }. Poll with GET /api/agent/scout/reddit/{runId}.GET /api/agent/gaps
POST /api/agent/gaps/generate {"competitor_urls": ["https://competitor1.com", "https://competitor2.com"]}
POST /api/agent/competitors/discover {"keywords": ["ai content marketing", "automated blogging"]}
POST /api/agent/competitors/scout {"domain": "https://competitor.com", "mode": "fast|ultimate"}
fast = 25 credits, ultimate = 50 creditsGET /api/agent/personas
Returns available writing personas (25 total). Pass the
slug as persona param in autopilot.
Writers: hemingway, proust, orwell, tolkien, nabokov, christie, bulgakov, dostoevsky, strugatsky, bradbury Tech Leaders: altman, musk, jobs, bezos, trump Entertainment: tarantino, nolan, ryanreynolds, keanureeves Creators: mrbeast, taylorswift, kanye, zendaya, timotheechalamet, billieeilish
Response: array of
{ slug, displayName, group, description }
POST /api/agent/autopilot { "topic": "How to Use AI for Content Marketing", "source_urls": ["https://example.com/article"], "language": "en", "size": "standard", "mode": "standard", "enable_search": false, "persona": "musk", "illustrations": true, "audio": true, "disable_competition": false, "auto_publish": true }
Required: either
topic or source_urls (at least one)
Optional:
topic — article topic (string, max 500 chars)source_urls — array of 1-3 URLs to extract text from and use as source material (2 credits per URL)size — mini (~500w), standard (~1000w, default), full (~1500w), pillar (~2500w)mode — standard (default, full pipeline) or turbo (ultra-cheap micro-articles, see below)enable_search (bool, default false) — enable web + X/Twitter search for fresh facts (turbo mode only)persona — writing style persona slug (call GET /api/agent/personas for list, e.g. "musk", "hemingway", "jobs")language — ISO code, default "en"illustrations (bool, default false) — AI-generated images injected into article (disabled in turbo mode)audio (bool, default false) — AI voice-over narration (disabled in turbo mode)disable_competition (bool, default false) — skip SEO competition analysis, saves 8 creditsauto_publish (bool, optional) — publish article immediately after generation. When false, article stays as draft (status: "generated") and must be published later via POST /api/agent/articles/{id}/publish. Default uses tenant setting (configurable in dashboard → Agent Settings). If no tenant setting, defaults to true.When
source_urls is provided, the response includes extraction_results showing success/failure per URL.
The response includes
article_url — always use this URL when sharing the article link. Do NOT construct URLs manually.
When
auto_publish is true (default), articles are auto-published and the URL works immediately. When false, the article is saved as a draft — the response returns status: "generated" instead of "published". Use POST /api/agent/articles/{id}/publish to publish it later.
/api/agent/me also returns blog_url — the tenant's blog root URL.
Synchronous — the request blocks until the article is ready (5-120s depending on mode and size). The response contains the complete article.
Ultra-cheap micro-article generation — 2-4 credits instead of 15-48. Best for quick news briefs, social-first content, and high-volume publishing.
Turbo (2 credits) — fast generation, no web search:
POST /api/agent/autopilot { "topic": "Latest AI Search Trends", "mode": "turbo", "language": "en" }
Turbo+ (4 credits) — adds fresh facts from web search & X/Twitter (10-25s):
POST /api/agent/autopilot { "topic": "Latest AI Search Trends", "mode": "turbo", "enable_search": true, "language": "en" }
What Turbo/Turbo+ does differently vs Standard:
Pricing:
| Mode | Search | Credits | Speed |
|---|---|---|---|
| Turbo | No | 2 | 5-15s |
| Turbo+ | Yes | 4 | 10-25s |
Compare with standard mode: mini=15, standard=20, full=33, pillar=48 credits.
When to use Turbo/Turbo+:
| Extension | Mini | Standard | Full | Pillar |
|---|---|---|---|---|
| Base article | 7 | 12 | 25 | 40 |
| + Intelligence (default on) | +8 | +8 | +8 | +8 |
| + Illustrations | +9 | +18 | +27 | +36 |
| + Audio | +10 | +20 | +35 | +55 |
| Full package | 34 | 58 | 95 | 139 |
Without extensions: same as before (mini=15, standard=20, full=33, pillar=48 credits).
POST /api/agent/adapt { "article_id": "uuid-of-article", "platforms": ["linkedin", "x_thread"], "include_ref_link": true }
Required:
article_id (UUID), platforms (1-3 unique values)
Platforms:
x_article, x_thread, linkedin, facebook, reddit, threads, instagram, instagram_reels, youtube_shorts
Optional:
include_ref_link (bool, default true) — append referral footer to each adaptation~5 credits per platform (varies by article length). Max 3 platforms per request.
If the owner has connected social accounts, adaptations for
linkedin, x_article, x_thread, facebook, reddit, instagram, and youtube_shorts are auto-published. The response includes platform_post_id for published posts.
Response:
{ "adaptations": [ { "platform": "linkedin", "content": "...", "credits_used": 5, "char_count": 1200, "published": true, "platform_post_id": "urn:li:share:123" } ], "total_credits": 10, "ref_link_appended": true }
Publish article content directly to social platforms without AI adaptation. 0 credits.
POST /api/agent/publish { "action": "publish_raw", "articleId": "uuid-of-article", "platform": "linkedin", "accountId": "uuid-of-social-account" }
Required:
action ("publish_raw"), articleId (UUID), platform, accountId (UUID)
Platforms:
linkedin, facebook, x_article, reddit, instagram
Optional:
subreddit (string) — required when platform is redditNotes:
Response:
{ "success": true, "action": "publish_raw", "adaptationId": "uuid", "platformPostId": "urn:li:share:456" }
POST /api/agent/session { "categories": ["AI marketing", "SEO tools"], "problems": ["how to rank higher"], "languages": ["en"], "interval_minutes": 720, "article_size": "mini", "disable_competition": false }
Required:
categories (1-5 strings)
Optional:
problems — specific problems to address (max 20)languages — ISO codes, default ["en"]interval_minutes — cron interval, 60-10080, default 720 (12h)article_size — mini (default), standard, full, pillardisable_competition (bool, default false)Creates and auto-starts a cron-based content session. Only one active session per tenant.
Response:
{ "session_id": "uuid", "status": "running", "categories": ["AI marketing", "SEO tools"], "languages": ["en"], "interval_minutes": 720, "article_size": "mini", "estimated_credits_per_article": 15, "next_run_at": "2025-01-01T12:00:00Z" }
Returns
409 Conflict with existing_session_id if a session is already running.
Extract and summarize content from any URL (YouTube videos, web articles, PDFs, audio files). Async — submit URL, poll for result.
Submit URL:
POST /api/agent/ingest { "url": "https://youtube.com/watch?v=abc123" }
202 Accepted with { id, status: "processing", content_type, credits_charged, poll_url }200 with cached result for 1 credityoutube_video, web_article, pdf_document, audio_filePoll Status:
GET /api/agent/ingest/{id}
status changes from "processing" to "completed" or "failed".{ id, status, content_type, summary, word_count, metadata, credits_charged }{ id, status: "failed", error_message } — credits are auto-refunded.Get Full Content:
GET /api/agent/ingest/{id}/content
Batch Ingest (up to 20 URLs):
POST /api/agent/ingest/batch { "urls": ["https://example.com/article1", "https://example.com/article2"], "callback_url": "https://your-server.com/webhook" }
{ total, accepted, failed, results: [{ url, status, job_id?, credits_charged }] }List Jobs:
GET /api/agent/ingest?limit=20&offset=0&status=completed
status: processing | completed | failed.Pricing:
| Content Type | Duration | Credits |
|---|---|---|
| web_article | — | 1 |
| pdf_document | — | 2 |
| youtube_video (short) | <10 min | 5 |
| youtube_video (medium) | 10-30 min | 15 |
| youtube_video (long) | 30-60 min | 30 |
| youtube_video (extra) | 60-120 min | 55 |
| audio_file (short) | <10 min | 3 |
| audio_file (medium) | 10-30 min | 8 |
| audio_file (long) | 30-60 min | 15 |
| audio_file (extra) | 60-120 min | 30 |
| cache hit (any) | — | 1 |
Workflow:
POST /api/agent/ingest with { "url": "..." } → get id and poll_urlGET /api/agent/ingest/{id} every 10s until status != "processing"summary and metadata from responseGET /api/agent/ingest/{id}/content for full extracted textPOST /api/agent/autopilot with topicGenerate PDF lead magnets (checklists, swipe files, frameworks) for lead capture.
Generate:
POST /api/agent/lead-magnets { "topic": "10-Step SEO Audit Checklist", "type": "checklist", // checklist | swipe_file | framework "niche": "digital_marketing", // optional "language": "en", // en|pt|de|es|fr|it (default: en) "platform": "linkedin", // twitter|linkedin (default: twitter) "generate_images": false, // true = 100 credits, false = 30 credits "auto_publish": false // hint for agent workflow }
{ id, status: "generating" }Check Status:
GET /api/agent/lead-magnets/{id}
status changes from "generating" to "draft".title, type, pdf_url.Publish:
PATCH /api/agent/lead-magnets/{id} { "status": "published" }
public_url.public_url in social posts for lead capture (visitors subscribe with email to download PDF).Workflow:
POST /api/agent/lead-magnets → get idGET /api/agent/lead-magnets/{id} every 10s until status != "generating"PATCH /api/agent/lead-magnets/{id} with { "status": "published" }public_url in a social postGenerate AI UGC viral videos with subtitles — from script to finished video.
Recommended flow:
/shorts/script — generate speech script from topic/shorts/avatar — generate AI avatar image (user approves)/shorts — generate video segment(s) with avatar + prompt + speech_text/shorts/merge — merge segments + add professional subtitles (if multi-segment)/shorts/publish — publish video directly to YouTube Shorts and/or Instagram ReelsGenerate Script:
POST /api/agent/shorts/script { "topic": "AI personas let you write as Elon Musk", "duration": "short", "style": "hook", "language": "en", "product_id": "optional-uuid" }
duration — short (10-12s, ~30 words) or long (20-30s, ~60 words, split into 2 parts)style — hook (attention grabber), educational (informative), cta (call to action)product_id — optional, enriches script with product knowledge{ script, word_count, estimated_duration_sec, parts, credits_charged }Generate Avatar:
POST /api/agent/shorts/avatar { "gender": "female", "origin": "latin", "age_range": "26-35", "type": "tech_founder", "location": "coffee_shop" }
gender — male | femaleorigin — european | asian | african | latin | middle_eastern | south_asianage_range — 18-25 | 26-35 (default) | 36-50type — tech_founder (default) | vibe_coder | student | executivelocation — coffee_shop (default) | dev_cave | street | car | home_office | podcast_studio | glass_office | rooftop | bedroom | park | gym{ avatar_url, r2_key, prompt_used, credits_charged }Generate Video Segment:
POST /api/agent/shorts { "prompt": "Close-up portrait 9:16, young Latina woman in coffee shop, natural lighting. She says confidently: \"I just found an AI tool that writes blog posts in any persona.\" Audio: no background music.", "avatar_url": "https://download.citedy.com/agent/avatars/...", "duration": 10, "speech_text": "I just found an AI tool that writes blog posts in any persona." }
prompt — scene description following 5-layer formula (scene, character, camera, speech, audio)avatar_url — URL from /shorts/avatar response (must be download.citedy.com or *.supabase.co)duration — 5, 10, or 15 secondsresolution — 480p (default) | 720paspect_ratio — 9:16 (default) | 16:9 | 1:1speech_text — optional, text for subtitle overlay (min 5, max 1000 chars){ id, status: "generating", video_url: null, credits_charged, estimated_seconds }GET /api/agent/shorts/{id} every 10s until status is "completed" or "failed"{ id, status: "completed", video_url, subtitles_applied, subtitle_warning }Merge Segments:
POST /api/agent/shorts/merge { "video_urls": ["https://download.citedy.com/...", "https://download.citedy.com/..."], "phrases": [ {"text": "I just found an AI tool"}, {"text": "that writes blog posts in any persona"} ], "config": {"words_per_phrase": 4, "font_size": 48, "text_color": "#FFFFFF"} }
video_urls — 2-4 URLs (must start with https://download.citedy.com/). Count must equal phrases countphrases — one per video segment, each { "text": "..." } (max 500 chars)config — optional: words_per_phrase (2-8), font_size (16-72), position_from_bottom (50-300), text_color / stroke_color (hex or named), stroke_width (0-5){ video_url, r2_key, duration, segment_durations, credits_charged }Publish Video:
POST /api/agent/shorts/publish { "video_url": "https://download.citedy.com/agent/shorts/.../video-sub.mp4", "speech_text": "I just found 8 hidden competitors in 3 minutes...", "targets": [ {"platform": "instagram_reels", "account_id": "uuid-of-ig-account"}, {"platform": "youtube_shorts", "account_id": "uuid-of-yt-account"} ], "privacy_status": "public" }
video_url — HTTPS URL from /shorts or /shorts/merge response (must be download.citedy.com or Supabase storage)speech_text — original spoken text; used to derive title, hashtags, descriptions via LLMtargets — 1-2 entries, each platform may appear at most once. Get account_id from GET /api/agent/me → connected_platformsprivacy_status — public (default), unlisted, private (YouTube only, ignored for Instagram){ results: [{ platform, ok, post_id?, error? }], metadata_provider, metadata_degraded, timings: { metadata_ms, total_ms }, credits_charged }Pricing:
| Step | Credits |
|---|---|
| Script | 1 |
| Avatar | 3 |
| Video (5s) | 60 |
| Video (10s) | 130 |
| Video (15s) | 185 |
| Merge + subtitles | 5 |
| Publish (IG Reels) | 5 |
| Publish (YT Shorts) | 0 |
| Full 10s video | 139 |
| Full 10s + publish both | 144 |
POST /api/agent/scan { "query": "AI content marketing trends", "mode": "deep", "limit": 10 }
query — search query (max 500 chars)mode — fast (2 credits, X only) | deep (4 credits, X + web) | ultra (6 credits, + HackerNews) | ultra+ (8 credits, + Reddit). If omitted, derived from tenant's scanSources settingslimit — 1-30, default 10{ results: [{ title, summary, url, source, knowledgeMatch? }], mode, cost, warnings? }knowledgeMatch with similarity scoresPOST /api/agent/post { "topic": "AI agents are the future of marketing", "platforms": ["linkedin", "x_thread"], "tone": "casual", "contentType": "short", "scheduledAt": "2026-03-01T09:00:00Z" }
topic — required, max 500 charsplatforms — optional, from settings default. Values: linkedin, x_article, x_thread, facebook, reddit, threads, instagram, instagram_reels, youtube_shortstone — optional, from settings defaultcontentType — short (default) | detailedscheduledAt — optional ISO datetime (must be future)trustLevel=autopilot and no scheduledAt, auto-schedules{ postId, adaptations: [{ id, platform }], scheduledAt, trust_level, auto_scheduled }POST /api/agent/publish { "adaptationId": "uuid", "action": "now", "platform": "linkedin", "accountId": "uuid" }
instagram_reels)action — now (publish immediately) | schedule (requires scheduledAt) | cancel (cancel scheduled)platform — facebook | linkedin | x_article | x_thread | reddit | threads | instagramaccountId — social account UUID (from /me connected_platforms)scheduledAt — ISO datetime, required for action=scheduleUpload product documents for context-aware content generation.
Upload document:
POST /api/agent/products { "title": "Our AI Writing Platform", "content": "Citedy is an AI-powered...", "source_type": "manual" }
source_type — upload (default) | url | manualList documents:
GET /api/agent/products
Delete document:
DELETE /api/agent/products/{id}
Search knowledge:
POST /api/agent/products/search {"query": "AI writing features", "limit": 5}
Read:
GET /api/agent/settings
Update:
PUT /api/agent/settings { "defaultPlatforms": ["linkedin", "x_article"], "contentTone": "professional", "imageStylePreset": "minimal", "trustLevel": "show_preview", "scanSources": ["x", "google"], "targetTimezone": "America/New_York", "publishSchedule": {"postsPerDay": 2, "slots": ["09:00", "17:00"]} }
defaultPlatforms — linkedin | x_article | x_thread | facebook | reddit | threads | instagram | instagram_reels | youtube_shortscontentTone — professional | casual | boldimageStylePreset — minimal | tech | boldtrustLevel — ask_all | show_preview | autopilotscanSources — x | google | hn | redditView timeline:
GET /api/agent/schedule?from=2026-03-01&to=2026-03-14&type=all
type — all | article | post | socialFind content gaps:
GET /api/agent/schedule/gaps?days=7&timezone=America/New_York
postsPerDay target.Get optimal time slots:
GET /api/agent/schedule/suggest
PUT /api/agent/image-style {"preset": "minimal"}
minimal | tech | boldPOST /api/agent/rotate-key
GET /api/agent/health
{ status, checks: { redis, supabase }, timestamp }./status)GET /api/agent/status
billing)social)schedule)knowledge)content)actions[]) with command hints and dashboard URLs.GET /api/agent/articles?limit=50&offset=0&status=published
{ articles: [...], total_articles }.status: published, generated (draft). Omit to get all.POST /api/agent/articles/{id}/publish
status: "generated" → "published").{ article_id, status: "publishing", message }.200 with { status: "published", message: "Article is already published" }.status: "generated". Other statuses return 409 Conflict.article.published webhook event.PATCH /api/agent/articles/{id} Content-Type: application/json{ "action": "unpublish" }
status: "published" → "generated").{ article_id, status: "generated", message }.status: "published". Other statuses return 409 Conflict.article.unpublished webhook event.DELETE /api/agent/articles/{id}
{ article_id, message: "Article deleted" }.article.deleted webhook event.GET /api/agent/me
Response includes:
blog_url — tenant's blog root URLtenant_balance — current credits + status (healthy/low/empty)rate_limits — remaining requests per categoryreferral — { code, url } for attributing signupsconnected_platforms — which social accounts are linked:{ "connected_platforms": [ { "platform": "linkedin", "connected": true, "account_name": "John Doe" }, { "platform": "x", "connected": false, "account_name": null }, { "platform": "facebook", "connected": false, "account_name": null }, { "platform": "reddit", "connected": false, "account_name": null }, { "platform": "instagram", "connected": false, "account_name": null } ] }
Use
connected_platforms to decide which platforms to pass to /api/agent/adapt for auto-publishing.
| Endpoint | Method | Cost |
|---|---|---|
| POST | free (public) |
| GET | free (public) |
| GET | free |
| GET | free |
| POST | free (1/hour) |
| GET | free |
| PUT | free |
| PUT | free |
| GET | free |
| GET | free |
| POST | free |
| PATCH | free (unpublish) |
| DELETE | free |
| POST | 2-8 credits (by mode) |
| POST | 2 credits |
| POST | 2-139 credits |
| POST | ~5 credits/platform |
| POST | 0 credits (5 for ) |
| POST | free (articles billed on generation) |
| GET | free |
| GET | free |
| GET | free (REST only, not MCP tool) |
| POST | 35-70 credits |
| GET | free (poll) |
| POST | 30 credits |
| GET | free (poll) |
| GET | free |
| POST | 40 credits |
| POST | 20 credits |
| POST | 25-50 credits |
| POST | 1 credit |
| GET | free |
| DELETE | free |
| POST | free |
| POST | 1-55 credits |
| GET | free |
| GET | free (poll) |
| GET | free |
| POST | 1-55 credits per URL |
| POST | 30-100 credits |
| GET | free (poll) |
| PATCH | free |
| POST | 1 credit |
| POST | 3 credits |
| POST | 60-185 credits (by duration) |
| GET | free (poll) |
| POST | 5 credits |
| POST | free |
| GET | free |
| DELETE | free |
| GET | free |
1 credit = $0.01 USD
Webhooks let Citedy push real-time event notifications to your server instead of polling.
POST /api/agent/webhooks { "url": "https://your-server.com/webhooks/citedy", "event_types": ["article.generated", "ingestion.completed"], "description": "Production webhook" }
url — must be https:// in productionevent_types — omit to receive all 15 event types (wildcard)description — optional labelid, url, secret, event_types, created_atsecret is shown only once — store it securely for signature verificationGET /api/agent/webhooks
{ webhooks: [...] }.DELETE /api/agent/webhooks/{id}
GET /api/agent/webhooks/deliveries?status=delivered&limit=20&offset=0
status: queued, delivering, delivered, failed, dead_lettered.{ deliveries: [...], total } with attempts, http status, error, duration.| Event | Triggered when |
|---|---|
| Article generation completed |
| Article published (auto or manual) |
| Article unpublished (→ draft) |
| Article permanently deleted |
| Article generation failed |
| Content ingestion job finished |
| Content ingestion job failed |
| Social post adaptation created |
| Lead magnet PDF generated |
| Lead magnet generation failed |
| Scout run started (X or Reddit) |
| Scout run completed (X or Reddit) |
| Recurring session published articles |
| Balance below threshold |
| Balance at 0 |
Every webhook delivery sends a JSON
WebhookEventEnvelope:
{ "event_id": "evt_abc123", "event_type": "article.generated", "api_version": "2026-02-25", "timestamp": "2026-02-25T10:00:00.000Z", "tenant_id": "...", "agent_id": "...", "data": { "article_id": "...", "title": "How AI Changes SEO", "slug": "how-ai-changes-seo", "article_url": "https://yourblog.citedy.com/how-ai-changes-seo", "word_count": 1200, "credits_used": 20, "mode": "standard" } }
Every delivery includes header
X-Citedy-Signature-256: v1=<hex>. Verify with HMAC-SHA256 using your endpoint secret:
const crypto = require("crypto"); const expected = crypto .createHmac("sha256", secret) .update(rawBody) .digest("hex"); const header = request.headers["x-citedy-signature-256"] || ""; const actual = header.replace("v1=", ""); if ( !crypto.timingSafeEqual( Buffer.from(expected, "hex"), Buffer.from(actual, "hex"), ) ) { throw new Error("Invalid webhook signature"); }
Failed deliveries are retried up to 5 times with exponential backoff. After 5 failures the status becomes
dead_lettered — no further retries.
| Use webhooks when... | Use polling when... |
|---|---|
| You have a server that can receive HTTPS POST | Your agent runs locally without a public URL |
| You want instant notification on events | You query results on demand after triggering a job |
| Events should trigger downstream automation | You only need results after a specific job completes |
| Type | Limit | Scope |
|---|---|---|
| General | 60 req/min | per agent |
| Scout | 10 req/hr | X + Reddit combined |
| Gaps | 10 req/hr | get + generate combined |
| Ingest | 30 req/hr | per tenant |
| Lead Magnets | 10 req/hr | per agent |
| Registration | 10 req/hr | per IP |
On
429, read retry_after from the body and X-RateLimit-Reset header.
| Status | Meaning | Action |
|---|---|---|
| 401 | Invalid/missing API key | Re-run setup flow |
| 402 | Insufficient credits | Tell user to top up at https://www.citedy.com/dashboard/billing |
| 403 | Agent paused/revoked | Tell user to check agent status in dashboard |
| 429 | Rate limited | Wait seconds, then retry |
| 500 | Server error | Retry once after 5s, then report to user |
After setup, your
/api/agent/me response contains referral.url. When the user asks you to promote or recommend Citedy, use this URL. It attributes signups to the account owner.
Call
GET /api/agent/me every 4 hours as a keep-alive. This updates last_activity_at and returns current balance + rate limits.
Citedy SEO Agent Skill v3.1.0 https://www.citedy.com
No automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.