CLI / cURL Guide
Use the IdeaLift REST API directly from your terminal. Copy-paste examples for every endpoint.
On this page
Prerequisites
- Get your API key from Dashboard → Integrations → API Keys
- Store it in an environment variable (recommended):
export IDEALIFT_API_KEY="elk_your_key_here"
- Base URL for all requests:
https://idealift.app/api/v1
Authentication
Every request requires an Authorization header with your API key:
curl https://idealift.app/api/v1/workspace \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
API keys are scoped — each key has specific permissions like ideas:read, ideas:write, etc. You can create multiple keys with different scopes.
Quick Start
Three commands to verify everything works:
curl https://idealift.app/api/v1/workspace \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Returns your workspace name, plan, and idea counts.
curl https://idealift.app/api/v1/ideas?limit=5 \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Returns the 5 most recent ideas with pagination metadata.
curl -X POST https://idealift.app/api/v1/ideas \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Add dark mode support",
"summary": "Users want a dark theme for nighttime usage",
"source": "api",
"category": "UX"
}'Creates a new idea and returns it with its generated ID.
Ideas
/ideasideas:readList ideas with filtering, search, and sorting.
Filter by status
curl "https://idealift.app/api/v1/ideas?status=planned&limit=20" \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Filter by source
curl "https://idealift.app/api/v1/ideas?source=slack" \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Search by keyword
curl "https://idealift.app/api/v1/ideas?search=dark+mode" \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Sort by votes (descending)
curl "https://idealift.app/api/v1/ideas?sort=voteCount&order=desc" \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
| Param | Type | Description |
|---|---|---|
| limit | int | Items per page (default 50, max 100) |
| cursor | string | Pagination cursor from previous response |
| status | string | captured, new, under_review, planned, in_progress, shipped, rejected, archived, duplicate |
| source | string | slack, discord, teams, api, chrome, intercom, zendesk, etc. |
| category | string | Filter by category name |
| search | string | Search in title and summary |
| sort | string | createdAt, voteCount, riceScore, signalCount |
| order | string | asc or desc (default: desc) |
| since | ISO date | Only ideas created after this date |
/ideas/:idideas:readGet a single idea with full details.
curl https://idealift.app/api/v1/ideas/IDEA_ID \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
/ideasideas:writeCreate an idea with metadata.
curl -X POST https://idealift.app/api/v1/ideas \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Export ideas to CSV",
"summary": "PMs need to share idea lists with stakeholders who prefer spreadsheets",
"source": "api",
"category": "Reporting",
"url": "https://feedback.example.com/thread/123"
}'| Field | Required | Description |
|---|---|---|
| title | Yes | Idea title (1–500 characters) |
| summary | No | Detailed description (max 5,000 chars) |
| source | No | Where it came from (defaults to "api") |
| category | No | Category name (max 100 chars) |
| url | No | Source URL for deduplication (max 2,000 chars) |
/ideas/:idideas:writeUpdate an idea's status, title, category, or RICE scores.
Change status to planned
curl -X PATCH https://idealift.app/api/v1/ideas/IDEA_ID \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "planned"}'Update RICE scores
curl -X PATCH https://idealift.app/api/v1/ideas/IDEA_ID \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"riceReach": 500,
"riceImpact": 3,
"riceConfidence": 80,
"riceEffort": 2
}'/ideas/:idideas:writeSoft-delete an idea (sets status to "deleted").
curl -X DELETE https://idealift.app/api/v1/ideas/IDEA_ID \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
/ideas/:id/voteideas:voteUpvote or downvote an idea.
# Upvote (default)
curl -X POST https://idealift.app/api/v1/ideas/IDEA_ID/vote \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"voter": "[email protected]", "value": 1}'
# Downvote
curl -X POST https://idealift.app/api/v1/ideas/IDEA_ID/vote \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"voter": "[email protected]", "value": -1}'/ideas/:id/signalsideas:readList signal history (AI-detected mentions from chat, support, etc.).
curl "https://idealift.app/api/v1/ideas/IDEA_ID/signals?limit=10" \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
/ideas/:id/decisionsideas:readList decision event history for an idea (status changes, closure reasons).
curl "https://idealift.app/api/v1/ideas/IDEA_ID/decisions" \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
/ideas/:id/customerscustomers:readList customers linked to an idea (with ARR/MRR data).
curl "https://idealift.app/api/v1/ideas/IDEA_ID/customers" \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Batch Operations
/ideas/batchideas:writeCreate up to 100 ideas in one request.
curl -X POST https://idealift.app/api/v1/ideas/batch \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ideas": [
{"title": "Add CSV export", "category": "Reporting"},
{"title": "Mobile push notifications", "category": "Mobile"},
{"title": "Slack thread replies", "category": "Integrations"}
]
}'Response includes per-item success/failure details.
/ideas/batch/statusideas:writeUpdate statuses for up to 100 ideas at once.
curl -X PATCH https://idealift.app/api/v1/ideas/batch/status \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"updates": [
{"id": "IDEA_ID_1", "status": "planned"},
{"id": "IDEA_ID_2", "status": "in_progress"},
{"id": "IDEA_ID_3", "status": "shipped"}
]
}'Roadmap & Analytics
/roadmap/stagesroadmap:readList all roadmap stages and their idea counts.
curl https://idealift.app/api/v1/roadmap/stages \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
/ideas/:id/roadmaproadmap:writeAssign an idea to a roadmap stage, or unassign by passing null.
# Assign to a stage
curl -X PUT https://idealift.app/api/v1/ideas/IDEA_ID/roadmap \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"stageId": "STAGE_ID"}'
# Unassign from roadmap
curl -X PUT https://idealift.app/api/v1/ideas/IDEA_ID/roadmap \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"stageId": null}'/analytics/summaryanalytics:readGet workspace analytics: idea counts by status, source, top categories, and average RICE scores.
curl https://idealift.app/api/v1/analytics/summary \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Webhooks
Subscribe to real-time events. See the Webhooks docs for payload formats.
/webhookswebhooks:manageList your webhook subscriptions.
curl https://idealift.app/api/v1/webhooks \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
/webhookswebhooks:manageCreate a webhook subscription (max 10 per workspace).
curl -X POST https://idealift.app/api/v1/webhooks \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/idealift",
"events": ["idea.created", "idea.status_changed"],
"name": "My CI/CD webhook"
}'Supported events: idea.created, idea.updated, idea.status_changed, idea.voted, idea.deleted, idea.assigned
/webhooks/:idwebhooks:manageDelete a webhook subscription.
curl -X DELETE https://idealift.app/api/v1/webhooks/WEBHOOK_ID \ -H "Authorization: Bearer $IDEALIFT_API_KEY"
Pagination
List endpoints use cursor-based pagination. The response includes a cursor field and a hasMore boolean.
# First page
curl "https://idealift.app/api/v1/ideas?limit=20" \
-H "Authorization: Bearer $IDEALIFT_API_KEY"
# Response includes: { "data": [...], "hasMore": true, "cursor": "abc123", "total": 87 }
# Next page — pass the cursor
curl "https://idealift.app/api/v1/ideas?limit=20&cursor=abc123" \
-H "Authorization: Bearer $IDEALIFT_API_KEY"Keep paginating until hasMore is false.
Error Handling
Errors return a JSON object with a code and message:
{
"error": {
"code": "validation_error",
"message": "Title is required (1-500 characters)",
"field": "title"
}
}| Status | Meaning |
|---|---|
| 400 | Bad Request — missing or invalid parameters |
| 401 | Unauthorized — invalid or missing API key |
| 403 | Forbidden — API key lacks required scope or plan limit reached |
| 404 | Not Found — resource doesn't exist or belongs to another workspace |
| 429 | Too Many Requests — rate limit exceeded |
| 500 | Internal Server Error |
Parse errors with jq
curl -s https://idealift.app/api/v1/ideas \ -H "Authorization: Bearer $IDEALIFT_API_KEY" \ | jq '.error // "OK"'
Rate Limits
Rate limits are enforced per API key. Check the response headers:
curl -si https://idealift.app/api/v1/ideas \ -H "Authorization: Bearer $IDEALIFT_API_KEY" \ | grep -i "x-ratelimit"
| Plan | Requests / minute | Ideas / month |
|---|---|---|
| Free | 60 | 30 |
| Pro | 300 | 500 |
| Team | 600 | Unlimited |
| Business | 1200 | Unlimited |
Tips & Tricks
Store your API key in an env var
Avoid pasting your key into every command and keep it out of shell history:
# Add to ~/.bashrc or ~/.zshrc export IDEALIFT_API_KEY="elk_your_key_here" # Then use $IDEALIFT_API_KEY in all requests
Pretty-print JSON with jq
# Pipe any response through jq for readable output curl -s https://idealift.app/api/v1/ideas?limit=3 \ -H "Authorization: Bearer $IDEALIFT_API_KEY" | jq . # Extract just idea titles curl -s https://idealift.app/api/v1/ideas \ -H "Authorization: Bearer $IDEALIFT_API_KEY" | jq '.data[].title' # Count ideas by status curl -s https://idealift.app/api/v1/analytics/summary \ -H "Authorization: Bearer $IDEALIFT_API_KEY" | jq '.byStatus'
Import ideas from a file
Create a JSON file and pipe it to the batch endpoint:
# ideas.json
{
"ideas": [
{"title": "Feature A", "category": "Core"},
{"title": "Feature B", "category": "UX"}
]
}
# Import
curl -X POST https://idealift.app/api/v1/ideas/batch \
-H "Authorization: Bearer $IDEALIFT_API_KEY" \
-H "Content-Type: application/json" \
-d @ideas.jsonExport all ideas to a file
curl -s "https://idealift.app/api/v1/ideas?limit=100" \ -H "Authorization: Bearer $IDEALIFT_API_KEY" \ | jq '.data' > my-ideas.json
Full Endpoint Reference
| Method | Endpoint | Scope |
|---|---|---|
| GET | /api/v1/workspace | workspace:read |
| GET | /api/v1/ideas | ideas:read |
| GET | /api/v1/ideas/:id | ideas:read |
| POST | /api/v1/ideas | ideas:write |
| PATCH | /api/v1/ideas/:id | ideas:write |
| DELETE | /api/v1/ideas/:id | ideas:write |
| POST | /api/v1/ideas/:id/vote | ideas:vote |
| GET | /api/v1/ideas/:id/customers | customers:read |
| GET | /api/v1/ideas/:id/signals | ideas:read |
| GET | /api/v1/ideas/:id/decisions | ideas:read |
| POST | /api/v1/ideas/batch | ideas:write |
| PATCH | /api/v1/ideas/batch/status | ideas:write |
| GET | /api/v1/roadmap/stages | roadmap:read |
| PUT | /api/v1/ideas/:id/roadmap | roadmap:write |
| GET | /api/v1/analytics/summary | analytics:read |
| GET | /api/v1/webhooks | webhooks:manage |
| POST | /api/v1/webhooks | webhooks:manage |
| DELETE | /api/v1/webhooks/:id | webhooks:manage |