Projects API
Create, list, and update projects, manage articles and keywords per project.
In Rankion a project is the central container — one domain per project, one team owner, and all sub-resources (articles, keywords, internal link maps, storylines) hang off it. Alongside this there are tracking projects as their own resource for AI visibility monitoring (see below).
CRUD
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| GET | /v1/projects |
List of all team projects (paginated) | — |
| POST | /v1/projects |
Create a new project | — |
| GET | /v1/projects/{id} |
Project detail | — |
| PUT | /v1/projects/{id} |
Update settings | — |
| DELETE | /v1/projects/{id} |
Delete project (soft) | — |
# List
curl -H "Authorization: Bearer $TOKEN" "$BASE/projects"
# Create
curl -X POST "$BASE/projects" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"My Blog","domain":"myblog.com","language":"en","country":"US"}'
Response (truncated):
{
"data": {
"id": 12,
"name": "My Blog",
"domain": "myblog.com",
"language": "en",
"country": "US",
"team_id": 7,
"created_at": "2026-05-01T08:30:00Z"
}
}
Project-scoped sub-resources
Articles
All article-related CRUD and generation endpoints attach to the project:
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| GET | /v1/projects/{project}/articles |
paginated (20/page) | — |
| POST | /v1/projects/{project}/articles |
Body: {title, slug?, content?, status?} |
— |
Full article API → Articles API.
Keywords
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| GET | /v1/projects/{project}/keywords |
Project keywords | — |
| POST | /v1/projects/{project}/keywords |
Create keyword | — |
| DELETE | /v1/keywords/{id} |
Delete keyword | — |
| POST | /v1/keywords/research |
Keyword research job | 5 |
| POST | /v1/keywords/{id}/expand |
A-Z expansion (async) | 10 |
| GET | /v1/keywords/{id}/expansions |
Results of an expansion | — |
Internal linking
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| POST | /v1/projects/{project}/internal-links/analyze |
Recompute the project-wide internal link map (async) | 5 |
| GET | /v1/articles/{id}/link-suggestions |
Suggestions for one article | — |
| PUT | /v1/link-suggestions/{id} |
Accept/reject a suggestion | — |
Other project sub-resources
| Endpoint family | Top endpoint |
|---|---|
| Storylines | GET/POST /v1/projects/{project}/storylines |
| Style profiles | GET/POST /v1/projects/{project}/style-profiles |
| Knowledge base | GET/POST /v1/projects/{project}/knowledge-base |
| Link lists | GET/POST /v1/projects/{project}/link-lists |
| Orphan scans | POST /v1/projects/{project}/orphan-scans/discover |
| Calendar | GET/POST /v1/projects/{project}/calendar |
| Project images | GET /v1/projects/{project}/images (legacy — primary path is the team-wide /v1/images) |
Tracking projects (their own resource!)
Tracking projects are separate from regular projects. They are the data foundation for AI Visibility Tracking — one brand per tracking project, one set of keywords, one set of platforms.
Endpoint namespace: /v1/tracking-projects/...
Wizard flow
The web UI has a 5-step wizard you can replicate 1:1 over the API:
| Step | Endpoint | Description |
|---|---|---|
| 1+2 | POST /v1/tracking-projects/analyze |
Analyze a domain/keyword, dispatches AnalyzeDomainJob. Body: {mode:"domain"|"keyword", domain?, keyword?, name?, language?, country?} → 202 + project_id |
| 3+4 | GET /v1/tracking-projects/{id}/analysis-status |
Polling: returns {analysis_status, suggested_keywords, suggested_competitors, suggested_prompts, suggested_personas, classification} |
| 5 | POST /v1/tracking-projects/{id}/activate |
Atomic: creates keywords/prompts/competitors and sets status=active |
# Step 1+2: start analysis
RESP=$(curl -s -X POST "$BASE/tracking-projects/analyze" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"mode":"domain","domain":"example.com","language":"en","country":"US"}')
PID=$(echo $RESP | jq -r .project_id)
# Step 3+4: poll until completed
while [ "$(curl -s "$BASE/tracking-projects/$PID/analysis-status" \
-H "Authorization: Bearer $TOKEN" | jq -r .analysis_status)" != "completed" ]; do
sleep 3
done
# Step 5: atomic activate
curl -X POST "$BASE/tracking-projects/$PID/activate" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"keywords":["best crm","crm software"],
"competitors":[{"domain":"hubspot.com"}],
"prompts":[{"prompt":"What is the best CRM?","category":"recommendation"}],
"platforms":["chatgpt","perplexity"],
"frequency":"weekly",
"with_search":true,
"reality_check_enabled":true
}'
Runtime operations
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/tracking-projects |
All tracking projects in the team |
| GET | /v1/tracking-projects/{id} |
Detail with current KPIs |
| PUT | /v1/tracking-projects/{id} |
Update settings (brand aliases, frequency, platforms, AVI toggle) |
| POST | /v1/tracking-projects/{id}/run |
Dispatch a manual tracking run |
| GET | /v1/tracking-projects/{id}/runs |
Run history |
| GET | /v1/tracking-projects/{id}/scores |
Score history for charts |
| GET | /v1/tracking-projects/{id}/avi |
Current AI Visibility Index (Reality Check) |
| POST | /v1/tracking-projects/{id}/generate-report |
Markdown report (10 credits, 1/30min limit) |
The complete table of all ~30 tracking endpoints lives in docs/API_REFERENCE.md.
Example workflow: project + first article
# 1) Create project
PID=$(curl -s -X POST "$BASE/projects" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Demo Site","domain":"demo.example","language":"en","country":"US"}' \
| jq -r .data.id)
# 2) Create article stub
ART=$(curl -s -X POST "$BASE/projects/$PID/articles" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"title":"Best AI Tools 2026","status":"draft"}' \
| jq -r .data.id)
# 3) Generate article content (5 credits, async)
curl -X POST "$BASE/articles/$ART/generate" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"keyword":"AI tools 2026","article_type":"blog","target_length":1500}'
# 4) Poll until ready
while [ "$(curl -s "$BASE/articles/$ART" \
-H "Authorization: Bearer $TOKEN" | jq -r .data.processing_status)" != "ready" ]; do
sleep 5
done
Detailed workflows for articles: Articles API.
Related: Authentication & API Tokens · Credits & Rate Limits · AI Visibility Tracking.