Use the live app here: https://clink-ai-linkedin-growth-28469836294.us-west1.run.app
clink is a FastAPI backend for generating a LinkedIn content strategy and post drafts using a multi-agent workflow.
It helps creators/professionals quickly get:
- a clear niche + angle,
- trending patterns that work in their space,
- a 30-day content calendar,
- on-demand post drafts with critiques.
Core agents (default flow):
- Niche Identifier: turns user inputs (and/or LinkedIn URL enrichment) into:
nichetarget_audienceunique_anglecontent_pillars
- Content Scraper: fetches trending posts for the niche (A2ANet if available; fallback to synthetic posts).
- Trend Analyzer: extracts patterns (best hooks/formats/timing, what to avoid).
- Strategy Builder: produces the content strategy including a 30-day calendar.
- Content Generator: generates a post draft for a selected day in the plan.
- Critic & Ranker: scores the generated post and suggests improvements.
Optional agents (separate endpoints):
- Competitor Analyzer: analyzes competitor post patterns (A2ANet-backed when configured).
- Trending Topics Scout: pulls trending topics/news relevant to the niche (A2ANet-backed when configured).
- User submits onboarding/profile info to
/api/analyze-profile. - Agents produce, in order:
- Niche positioning
- Scraped/synthetic trending posts
- Trend analysis
- 30-day strategy/calendar
- User requests a post for a specific day; the critic auto-scores it.
The frontend should consume the NDJSON stream from analysis to show a live “agents working” feed.
- User submits onboarding/profile info
- Agents produce:
- niche positioning
- trending post signals (scraped or synthetic)
- trend analysis
- 30-day strategy/calendar
- User can request on-demand post generation for any day in the calendar
- A critic agent automatically scores and gives feedback on the generated post
- Python 3.13+
pip(recommended inside a virtualenv)
bash python -m venv .venv source .venv/bin/activate
Windows (PowerShell):
powershell python -m venv .venv ..venv\Scripts\Activate.ps1
bash pip install -r requirements.txt
bash uvicorn main:app --reload --host 0.0.0.0 --port 8000
- Health check:
http://127.0.0.1:8000/api/health - API docs (Swagger):
http://127.0.0.1:8000/docs
Some endpoints/features can use A2ANet if configured.
Set an environment variable:
bash export A2ANET_API_KEY="your_key_here"
Windows (PowerShell):
powershell $env:A2ANET_API_KEY="your_key_here"
Restart the server after setting it.
If A2ANET_API_KEY is not set, the backend still works using local fallbacks.
Local dev: http://127.0.0.1:8000
GET /api/health
Response
json { "status": "ok" }
POST /api/analyze-profile
This endpoint returns NDJSON (newline-delimited JSON) so the frontend can show a live “agent feed”.
Request body (example)
json { "background": "Software engineer building AI products", "skills": ["Python", "ML", "System Design"], "interests": ["Startups", "AI"], "current_role": "Engineer", "goals": ["Thought leadership", "Get consulting clients"] }
Response
Content-Type: application/x-ndjson- Multiple JSON lines including a final line that contains
user_id.
Example (shape only)
json { "agent": "System", "status": "started", "message": "..." } { "agent": "Niche Identifier", "status": "completed", "data": { "...": "..." } } { "agent": "Content Scraper", "status": "completed", "data": { "...": "..." } } { "agent": "Trend Analyzer", "status": "completed", "data": { "...": "..." } } { "agent": "Strategy Builder", "status": "completed", "data": { "...": "..." } } { "agent": "System", "status": "complete", "user_id": "..." }
cURL example
bash curl -N -X POST "[http://127.0.0.1:8000/api/analyze-profile](http://127.0.0.1:8000/api/analyze-profile)"
-H "Content-Type: application/json"
-d '{"background":"Software engineer","skills":["Python"],"interests":["AI"],"current_role":"Engineer","goals":["Thought leadership"]}'
GET /api/user/{user_id}/state
Response
json { "user_id": "string", "state": { "NICHE_IDENTIFIED": { "...": "..." }, "SCRAPED_CONTENT": { "...": "..." }, "TREND_ANALYSIS": { "...": "..." }, "STRATEGY_READY": { "...": "..." }, "CONTENT_GENERATED": { "...": "..." }, "CONTENT_SCORED": { "...": "..." } }, "ready_for_generation": true }
Notes:
stateis in-memory. If the server restarts, state resets.
GET /api/user/{user_id}/messages-stream
Returns NDJSON stream of messages published on the message bus for this user.
Use this if your frontend wants a live feed without calling /state repeatedly.
POST /api/user/{user_id}/generate-post
Generates a post based on a provided day plan and the previously computed user context (niche + trends + strategy). The critic agent evaluates it automatically.
Request body (example)
json { "day_number": 1, "topic": "My biggest AI mistake", "format": "story", "pillar": "AI mistakes to avoid", "hook_angle": "Vulnerability/failure", "cta_type": "ask_question" }
Response
json { "post": { "hook": "...", "body": "...", "cta": "...", "hashtags": ["#..."], "full_post": "...", "engagement_prediction": "High", "authenticity_score": 90, "why_this_works": "..." }, "critique": { "scores": { "clarity": 8, "authenticity": 9, "engagement_potential": 8, "alignment": 9, "hook_quality": 9 }, "overall_score": 87, "strengths": ["..."], "improvements": ["..."], "improved_hook": "...", "feedback": "...", "verdict": "Use as-is / Minor edits needed", "edit_suggestions": [] } }
Errors
400if profile analysis hasn’t produced the required context yet.
POST /api/analyze-competitors
Analyzes competitor posting patterns. Uses A2ANet when configured; otherwise returns a local heuristic response.
Request (example)
json { "user_id": "your-user-id", "competitor_urls": [ }
latex_unknown_tag
Response JSON analysis (format usage, winning topics, tone, gaps, etc.)
POST /api/find-trending-topics
Returns trending topics for the user’s niche. Uses A2ANet when configured; otherwise returns local synthetic topics.
Request (example)
json { "user_id": "your-user-id" }
Response
json { "niche": "string", "topics": , "count": 5 }
- This backend stores user state in memory. For production, you would typically add persistence (Redis/DB).
- CORS is wide open (
*) for development convenience.