API Reference
Canny's API lets you access and modify your Canny data programmatically. We also support webhooks, where we notify your server of events as they happen.
The API expects the request to use the POST HTTP method, the body as JSON, and the Content-Type header set to "application/json".
This API enables you to seamlessly integrate Canny with your existing services.
Authentication
API requests must be authenticated by including your secret API key. You can find your secret API key in your company settings. Store it on your server and don't share it.
You can include your secret API key in a request by adding it as a POST parameter with key apiKey.
$ curl https://canny.io/api/v1/boards/list \
-d apiKey=YOUR_API_KEYPagination
Endpoints which list many results will have a limit on the number of results that can be returned, and pagination is the mechanism to retrieve results beyond that limit. To fetch more results, make a subsequent request with the necessary pagination parameters.
There are two approaches to pagination in the Canny API:
- Cursor: Request returns a cursor, which is used to fetch the next page.
- Skip: The skip parameter allows you to bypass the first N results.
Not all endpoints use the same approach, review the documentation for each endpoint to understand how to paginate.
$ curl https://canny.io/api/v2/users/list \
-d apiKey=YOUR_API_KEY \
-d cursor=NTUzYzNlZjhiOGNkY2QxNTAxYmExMjNhXzIwMjUtMDItMDRUMTY6NDA6MDcuNTQxWl8x \
-d limit=10$ curl https://canny.io/api/v1/posts/list \
-d apiKey=YOUR_API_KEY \
-d skip=10 \
-d limit=10Rate limits
Requests are counted per API key across every endpoint, in one-second, one-minute and one-hour windows. The allowance depends on your plan.
Businessper keyCore, Starter, Growth, Proper keyFreeper keyRequests are also counted per IP address, with the same allowance as a Business key. If several keys share one address, contact support and we can raise it.
Every response includes headers describing the window closest to its limit. When a limit is exceeded the request is not processed and the response has status 429 with a Retry-After header. Wait that many seconds before retrying.
X-RateLimit-LimitintegerX-RateLimit-RemainingintegerX-RateLimit-Resetunix timestampRetry-AfterintegerFor bulk work such as syncing users, spread requests out or run a scheduled job that stays under the hourly limit rather than sending updates as they happen.
HTTP/1.1 200 OK
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 587
X-RateLimit-Reset: 1790600460HTTP/1.1 429 Too Many Requests
Retry-After: 37
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1790600460
{"error":"slow down"}Boards
Boards are the high-level objects where your users can post and vote on ideas for a specific topic, typically feature requests. The API allows you to fetch a specific board, or a list of all boards for your company.
The board object
idstringcreatedstringisPrivatebooleannamestringpostCountnumberprivateCommentsbooleanurlstring{
"id": "6a2889c586d7b8843bf4cf01",
"created": "2017-07-15T22:11:00.000Z",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
}Retrieve board
Retrieves the details of an existing board, specified by its id.
apiKeystringrequiredidstringrequiredReturns
Returns a board object, if a valid id was supplied.
https://canny.io/ api/ v1/ boards/ retrieve$ curl https://canny.io/api/v1/boards/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf01{
"id": "6a2889c586d7b8843bf4cf01",
"created": "2017-07-15T22:11:00.000Z",
"isPrivate": true,
"name": "Feature Requests",
"postCount": 123,
"privateComments": false,
"url": "https://your-company.canny.io/admin/board/feature-requests"
}List all boards
Returns a list of all boards associated with your company, in no particular order.
apiKeystringrequiredReturns
A dictionary with a "boards" property that contains an array of board objects.
https://canny.io/ api/ v1/ boards/ list$ curl https://canny.io/api/v1/boards/list -X POST \
-d apiKey=YOUR_API_KEY{
"boards": [{
"id": "6a2889c586d7b8843bf4cf01",
"created": "2026-11-01T04:00:00.000Z",
"isPrivate": true,
"name": "Feature Requests",
"postCount": 123,
"privateComments": false,
"token": "11111111-2222-3333-4444-555555555555",
"url": "https://your-company.canny.io/admin/board/feature-requests"
}, {
"id": "6a2889c586d7b8843bf4cf05",
"created": "2026-11-01T04:00:00.000Z",
"isPrivate": false,
"name": "Bug Reports",
"postCount": 42,
"privateComments": true,
"token": "11111111-2222-3333-4444-555555555555",
"url": "https://your-company.canny.io/admin/board/bug-reports"
}]
}Categories
Posts can be assigned categories. Each category is for a specific board, not company-wide.
Our API allows you to list, and retrieve categories. You can also change categories of posts.
The category object
idstringboardBoard objectcreatedstringnamestringparentIDstring | nullpostCountnumberurlstring{
"id": "6a2889c586d7b8843bf4cf0b",
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2026-11-01T04:00:00.000Z",
"name": "Example Category Name",
"parentID": "6a2889c586d7b8843bf4cf18",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=example-category-name"
}Retrieve category
Retrieves the details of an existing category, specified by its id.
apiKeystringrequiredidstringrequiredReturns
Returns a category object, if a valid id was supplied.
https://canny.io/ api/ v1/ categories/ retrieve$ curl https://canny.io/api/v1/categories/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf0b{
"id": "6a2889c586d7b8843bf4cf0b",
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2026-11-01T04:00:00.000Z",
"name": "Example Category Name",
"parentID": "6a2889c586d7b8843bf4cf18",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=example-category-name"
}List categories
Returns a list of categories. Include parameters to specify board and pagination. Sorted by newest.
apiKeystringrequiredboardIDstringoptionallimitnumberoptionalskipnumberoptionalReturns
A dictionary with a "categories" property that contains an array of tag objects. There's also a "hasMore" property that specifies whether this query returns more categories than the limit.
https://canny.io/ api/ v1/ categories/ list$ curl https://canny.io/api/v1/categories/list -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=6a2889c586d7b8843bf4cf01{
"categories": [{
"id": "6a2889c586d7b8843bf4cf0b",
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2026-11-01T04:00:00.000Z",
"name": "Example Category Name",
"parentID": "6a2889c586d7b8843bf4cf18",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=example-category-name"
}],
"hasMore": false,
}Create category
Creates a new category.
apiKeystringrequiredboardIDstringrequirednamestringrequiredparentIDstringoptionalsubscribeAdminsbooleanrequiredReturns
Upon success, returns an object with a single key: id.
https://canny.io/ api/ v1/ categories/ create$ curl https://canny.io/api/v1/categories/create -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=6a2889c586d7b8843bf4cf01 \
-d name="new category" \
-d parentID=6a2889c586d7b8843bf4cf17 \
-d subscribeAdmins=true
{
"id": "6a2889c586d7b8843bf4cf09",
}Delete category
Deletes a category If the category does not have sub categories.
apiKeystringrequiredcategoryIDstringrequiredReturns
Returns "success" if the category was successfully deleted.
https://canny.io/ api/ v1/ categories/ delete$ curl https://canny.io/api/v1/categories/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d categoryID=6a2889c586d7b8843bf4cf0c"successEntries
A changelog is simply a list of entries. The API allows you to create, update, publish, schedule, delete, and fetch the list of entries associated with your changelog.
The changelog entry object
idstringcreatedstringlabelsarraylastSavedstringmarkdownDetailsstringplaintextDetailsstringpostsarraypublishedAtstring | nullreactionsobject | nullscheduledForstring | nullstatusstringtitlestringtypesarrayurlstring{
"id": "6a2889c586d7b8843bf4cf08",
"created": "2026-11-01T04:00:00.000Z",
"labels": [{
"created": "2026-11-01T04:00:00.000Z",
"entryCount": 3,
"id": "6a2889c586d7b8843bf4cf0a",
"name": "Mobile",
"url": "https://your-company.canny.io/admin/changelog?labels=mobile"
}],
"lastSaved": "2026-11-01T04:00:00.000Z",
"markdownDetails": "# heading\n**bold**\n[link](https://canny.io)",
"plaintextDetails": "heading\nbold\nlink",
"posts": [{
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"category": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"details": "Post details",
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}],
"linkedIssueIDs": ["123"]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
}],
"publishedAt": "2026-11-01T04:00:00.000Z",
"reactions": {
"like": 2
},
"scheduledFor": null,
"status": "published",
"title": "Entry title",
"types": ["new", "improved"],
"url": "https://your-company.canny.io/changelog/entry-title"
}Create entry
Creates a new changelog entry, and optionally publishes or schedules it.
apiKeystringrequiredtitlestringrequireddetailsstringrequiredtypestringoptionalnotifybooleanoptionalpublishedbooleanoptionalpublishedOnstringoptionalscheduledForstringoptionallabelIDsarrayoptionalpostIDsarrayoptionalReturns
Upon success, returns an object with a single key: id.
https://canny.io/ api/ v1/ entries/ create$ curl https://canny.io/api/v1/entries/create -X POST \
-d apiKey=YOUR_API_KEY \
-d title="Sample entry" \
-d details="Some details..." \
-d type="fixed" \
{
"id": "6a2889c586d7b8843bf4cf09"
}List entries
Returns a list of changelog entries. Unless filtered by status, this includes drafts and scheduled entries.
To request translated changelog items, use the Accept-Language header in your HTTP request to specify the preferred language for the response.
apiKeystringrequiredlabelIDsarrayoptionallimitnumberoptionalskipnumberoptionalsortstringoptionalstatusstringoptionaltypestringoptionalReturns
A dictionary with a "entries" property that contains an array of entry objects. There's also a "hasMore" property that specifies whether this query returns more entries than the limit.
https://canny.io/ api/ v1/ entries/ list$ curl https://canny.io/api/v1/entries/list -X POST \
-d apiKey=YOUR_API_KEY{
"hasMore": false,
"entries": [{
"id": "6a2889c586d7b8843bf4cf08",
"created": "2026-11-01T04:00:00.000Z",
"labels": [{
"id": "6a2889c586d7b8843bf4cf15",
"created": "2026-11-01T04:00:00.000Z",
"entryCount": 4,
"name": "Feature",
"url": "https://your-company.canny.io/admin/changelog?labels=feature"
}],
"lastSaved": "2026-11-01T04:00:00.000Z",
"markdownDetails": "# heading\n**bold**\n[link](https://canny.io)",
"plaintextDetails": "heading\nbold\nlink",
"posts": [{
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"category": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"details": "Post details",
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}],
"linkedIssueIDs": ["123"]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
}],
"publishedAt": "2026-11-01T04:00:00.000Z",
"reactions": {
"like": 2
},
"scheduledFor": null,
"status": "published",
"title": "Entry title",
"types": ["new", "improved"],
"url": "https://your-company.canny.io/changelog/entry-title"
}]
}Update entry
Updates the content of an existing changelog entry. Only the arguments you provide are changed; omitted arguments are left untouched. This does not change whether the entry is published or scheduled.
apiKeystringrequiredentryIDstringrequireddetailsstringoptionallabelIDsarrayoptionalnotifybooleanoptionalpostIDsarrayoptionaltitlestringoptionaltypesarrayoptionalReturns
Returns "success" if the entry was updated successfully.
https://canny.io/ api/ v1/ entries/ update$ curl https://canny.io/api/v1/entries/update -X POST -d '{
"apiKey": "YOUR_API_KEY",
"entryID": "6a2889c586d7b8843bf4cf09",
"title": "Updated entry title",
"details": "Updated entry details",
"types": ["new", "improved"]}' \
-H "Content-Type: application/json"successChange entry status
Publishes, schedules, unpublishes, or unschedules a changelog entry. Publishing emails users if the entry has notify enabled. Setting an entry to the status it already has does nothing, except that a scheduled entry is rescheduled to the new scheduledFor date.
apiKeystringrequiredentryIDstringrequiredstatusstringrequiredpublishedOnstringoptionalscheduledForstringoptionalReturns
Returns "success" if the status was changed successfully.
https://canny.io/ api/ v1/ entries/ change_status$ curl https://canny.io/api/v1/entries/change_status -X POST \
-d apiKey=YOUR_API_KEY \
-d entryID=6a2889c586d7b8843bf4cf09 \
-d status=scheduled \
-d scheduledFor=2026-12-01T17:00:00.000Z \
successDelete entry
Deletes a changelog entry, whether it is a draft, scheduled, or published. Deleting an entry that is already deleted does nothing.
apiKeystringrequiredentryIDstringrequiredReturns
Returns "success" if the entry was deleted successfully.
https://canny.io/ api/ v1/ entries/ delete$ curl https://canny.io/api/v1/entries/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d entryID=6a2889c586d7b8843bf4cf09 \
successPortal Comments
Portal comments are left by users and admins on posts. They are always associated with a post. The API allows you to fetch a specific comment, or a list of comments for a post.
The portal comment object
idstringauthorUser objectboardBoard objectcreatedstringimageURLsarrayinternalbooleanlikeCountnumbermentionsarrayparentIDstring | nullpostPost objectprivatebooleanreactionsobject | nullstatusstring | nullvaluestring{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2026-11-01T04:00:00.000Z",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"internal": false,
"likeCount": 2,
"mentions": [],
"parentID": "6a2889c586d7b8843bf4cf11",
"post": {
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf0d",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
},
"private": false,
"reactions": {
"like": 2
},
"status": null,
"value": "Some cool comment"
}Retrieve portal comment
Retrieves the details of an existing portal comment, specified by its id.
apiKeystringrequiredidstringrequiredReturns
Returns a portal comment object, if a valid id was supplied.
https://canny.io/ api/ v1/ comments/ retrieve$ curl https://canny.io/api/v1/comments/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf05{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2026-11-01T04:00:00.000Z",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"internal": false,
"likeCount": 2,
"mentions": [],
"parentID": "6a2889c586d7b8843bf4cf11",
"post": {
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"eta": "February 2026",
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
},
"private": false,
"reactions": {
"like": 2
},
"value": "Some cool comment"
}List portal comments
Returns a list of portal comments. Include parameters to specify post, board, and pagination. Sorted by newest.
apiKeystringrequiredauthorIDstringoptionalboardIDstringoptionalcompanyIDstringoptionalcursorstringoptionallimitnumberoptionalpostIDstringoptionalReturns
A dictionary with an "items" property that contains an array of portal comment objects. There's also a "hasNextPage" property that specifies whether there are more comments available, and a "cursor" property that can be used to fetch the next page of results.
https://canny.io/ api/ v2/ comments/ list$ curl https://canny.io/api/v2/comments/list -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf0f{
"cursor": "eyJhZnRlciI6eyJfaWQiOiI1NTNjM2VmOGI4Y2RjZD...",
"hasNextPage": true,
"items": [{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2026-11-01T04:00:00.000Z",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"internal": false,
"likeCount": 2,
"mentions": [],
"parentID": "6a2889c586d7b8843bf4cf11",
"post": {
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
},
"private": false,
"reactions": {
"like": 2
},
"status": null,
"value": "Some cool comment"
}]
}Create portal comment
Creates a new portal comment.
You may also want to use the Create or update user endpoint to make sure the comment author's account exists (and fetch their id).
apiKeystringrequiredauthorIDstringrequiredcreatedAtstringoptionalimageURLsarrayoptionalinternalbooleanoptionalparentIDstringoptionalpostIDstringrequiredshouldNotifyVotersbooleanoptionalvaluestringrequiredReturns
Upon success, returns an object with a single key: id.
https://canny.io/ api/ v1/ comments/ create$ curl https://canny.io/api/v1/comments/create -X POST \
-d apiKey=YOUR_API_KEY \
-d authorID=6a2889c586d7b8843bf4cf05 \
-d postID=6a2889c586d7b8843bf4cf09 \
-d value="This is the comment's value"{
"id": "6a2889c586d7b8843bf4cf0c",
}Delete portal comment
Deletes a portal comment.
apiKeystringrequiredcommentIDstringrequiredReturns
Returns "success" if the comment was successfully deleted.
https://canny.io/ api/ v1/ comments/ delete$ curl https://canny.io/api/v1/comments/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d commentID=6a2889c586d7b8843bf4cf0c"successCompanies
Companies are created by associating them to users using Canny's SDK, SSO tokens, or the API. The API allows you to delete a specific company.
The company object
idstringcreatedstringcustomFieldsobjectdomainstring | nullmemberCountnumbermonthlySpendnumber | nullnamestring{
"id": "1234567890",
"created": "2026-11-01T04:00:00.000Z",
"customFields": {
"plan": "Premium"
},
"domain": "acme.com",
"memberCount": 12,
"monthlySpend": 1000,
"name": "Acme, Inc."
}List companies
Returns a list of all companies associated with your company, ordered by created date.
apiKeystringrequiredsearchstringoptionalsegmentstringoptionallimitnumberoptionalcursorstringoptionalReturns
A dictionary with a "companies" property that contains an array of company objects. You'll also receive a "hasNextPage" boolean indicating whether additional companies are available and a "cursor" string to request the next page. If "search" is provided, "hasNextPage" will always be false and "cursor" will be null.
https://canny.io/ api/ v2/ companies/ list$ curl https://canny.io/api/v2/companies/list -X POST \
-d apiKey=YOUR_API_KEY \
-d limit=100 \
-d cursor=NTUzYzNlZjhiOGNkY2QxNTAxYmExMjNhXzIwMjUtMDItMDRUMTY6NDA6MDcuNTQxWl8x{
"hasNextPage": true,
"cursor": "NTUzYzNlZjhiOGNkY2QxNTAxYmExMjNhXzIwMjUtMDItMDRUMTY6NDA6MDcuNTQxWl8x",
"companies": [
{
"id": "company1",
"created": "2022-06-17T12:44:38.797Z",
"customFields": {
"number": 1,
"bool": true,
"string": "test"
},
"domain": "example.com",
"memberCount": 5,
"monthlySpend": 100.23,
"name": "company 1"
}
]
}Create company
If you want to create a company, this can be accomplished by associating it to a user via the Create or Update User endpoint.
Update company
Given a company ID, this endpoint updates the company with the data supplied
If you have company syncing integrations in place (e.g., Hubspot, Salesforce, SSO Tokens, Canny Identify, ...), the fields updated with this endpoint might be overwritten.
apiKeystringrequiredidstringrequiredcreateddateoptionalcustomFieldsobjectoptionaldomainstringoptionalmonthlySpendintegeroptionalnamestringoptionalReturns
Upon success, returns an object with a single key: id.
https://canny.io/ api/ v1/ companies/ update$ curl https://canny.io/api/v1/companies/update -X POST -d '{
"apiKey": "YOUR_API_KEY",
"id": "company1",
"created": "2026-11-01T04:00:00.000Z",
"customFields": {
"number": "12",
"string": "value"
"boolean": true,
},
"domain": "acme.com",
"monthlySpend": 500.59,
"name": "company 1"}' \
-H "Content-Type: application/json"{
"id": "company1"
}Delete company
Deletes a company.
apiKeystringrequiredcompanyIDstringrequiredReturns
Returns "success" if the company was successfully deleted.
https://canny.io/ api/ v1/ companies/ delete$ curl https://canny.io/api/v1/companies/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d companyID=company1"successGroups
Groups let you organize ideas within a company. They can be nested to build a hierarchy and are often used to scope ownership or product areas.
The Groups API allows you to list your groups.
The group object
idstringnamestringdescriptionstringparentIDstring | nullurlNamestring{
"id": "6a2889c586d7b8843bf4cf0b",
"name": "Product",
"description": "All ideas related to the product surface area.",
"parentID": "6a2889c586d7b8843bf4cf0a",
"urlName": "product"
}List groups
Returns a paginated list of groups for your company.
apiKeystringrequiredcursorstringoptionallimitnumberoptionalReturns
A dictionary with an "items" array of group objects, a "hasNextPage" boolean indicating if more results are available, and a "cursor" string to fetch the next page when hasNextPage is true.
https://canny.io/ api/ v1/ groups/ list$ curl https://canny.io/api/v1/groups/list -X POST \
-d apiKey=YOUR_API_KEY \
-d limit=10{
"cursor": "eyJhZnRlciI6eyJfaWQiOiI1NTNjM2VmOGI4Y2RjZD...",
"hasNextPage": true,
"items": [{
"id": "6a2889c586d7b8843bf4cf02",
"name": "Product",
"description": "Ideas related to the product surface area.",
"urlName": "product"
}]
}Retrieve group
Retrieves the details of an existing group, specified by its id or urlName.
apiKeystringrequiredidstringoptionalurlNamestringoptionalReturns
Returns a group object, if a valid id or urlName was supplied.
https://canny.io/ api/ v1/ groups/ retrieve$ curl https://canny.io/api/v1/groups/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf02{
"id": "6a2889c586d7b8843bf4cf02",
"name": "Product",
"description": "Ideas related to the product surface area.",
"urlName": "product"
}Ideas
An idea is an object that represents a feature request or feedback item. Ideas can be organized into groups, have parent-child relationships, and include custom fields. The API allows you to fetch a list of ideas with filtering, sorting, and pagination options.
The idea object
idstringchildCountnumberauthorUser object | nullcreatedstringdescriptionstringgroupGroup object | nullownerUser object | nullparentPartial idea object | nullsourceSource objectstatusStatus object | nulltitlestringupdatedAtstring | nullurlNamestring{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"childCount": 1,
"created": "2026-11-01T04:00:00.000Z",
"description": "Test idea description",
"group": {
"id": "6a2889c586d7b8843bf4cf02",
"name": "Feature Requests",
"description": "Feature requests are ideas for new features or improvements to the product.",
"parentID": "6a2889c586d7b8843bf4cf01",
"urlName": "feature-requests"
},
"owner": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"parent": {
"id": "6a2889c586d7b8843bf4cf04",
"title": "Parent Idea",
"urlName": "parent-idea"
},
"source": {
"name": "canny",
"type": "web"
},
"status": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Under Review",
"type": "Active",
"urlName": "under-review"
},
"title": "An awesome feature request",
"updatedAt": "2026-11-01T04:00:00.000Z",
"urlName": "an-awesome-feature-request"
}The filtering object
filtersarrayAn array of filters to apply to the ideas. Should contain, resource, condition and value.
Resources: ideaDefaultField.
Conditions: Should be one of the ones listed below.
Value:
- fieldID: The ID of the field to filter by. Should be one of the ones listed below.
- value: The value to filter by. Should be one of the ones listed below.
Default Field IDs: "author", "board", "category", "created", "description", "group", "lastAdminPortalResponse", "owner", "portalAuthor", "portalETA", "portalStatus", "status", "statusChanged", "tags", "themes", "title", "type"
- Text Field: "isEmpty", "isNotEmpty", "contains", "notContains"
- Numeric Field: "equals", "doesNotEqual", "greaterThan", "lessThan"
- Alphanumeric Field: "isEmpty", "isNotEmpty", "contains", "notContains"
- Dropdown Field: "is", "isNot", "isDropdownSet", "isDropdownNotSet"
- Multiselect Field: "isOneOf", "isNotOneOf", "isMultiselectSet", "isMultiselectNotSet"
- Boolean Field: "isTrue", "isFalse"
- Date Field: "isDateSet", "isDateNotSet", "isBefore", "isAfter", "isBetween"
filtersOperatorstring{
"filters": [
{
"resource": "ideaDefaultField",
"condition": "is",
"value": {
"fieldID": "title",
"value": "My Awesome Idea"
}
}
],
"filtersOperator": "all"
}List ideas
Returns a list of ideas. Include parameters to specify pagination, filtering, and sorting.
apiKeystringrequiredcursorstringoptionalfilteringFiltering objectoptionallimitnumberoptionalparentIDstringoptionalsearchstringoptionalsortobjectoptionalReturns
A dictionary with an "items" property that contains an array of idea objects. There's also a "hasNextPage" property that specifies whether this query returns more ideas than the limit, and a "cursor" property that can be used to fetch the next page of results when hasNextPage is true.
https://canny.io/ api/ v1/ ideas/ list$ curl https://canny.io/api/v1/ideas/list -X POST \
-d apiKey=YOUR_API_KEY \
-d limit=10{
"cursor": "eyJhZnRlciI6eyJfaWQiOiI1NTNjM2VmOGI4Y2RjZD...",
"hasNextPage": true,
"items": [{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "jane@example.com",
"isAdmin": false,
"name": "Jane Doe",
"url": "https://your-company.canny.io/admin/users/jane-doe",
"userID": "5678"
},
"childCount": 1,
"created": "2026-11-01T04:00:00.000Z",
"description": "Test idea description",
"group": {
"id": "6a2889c586d7b8843bf4cf02",
"name": "Feature Requests",
"description": "Feature requests are ideas for new features or improvements to the product.",
"urlName": "feature-requests"
},
"owner": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"parent": {
"id": "6a2889c586d7b8843bf4cf04",
"title": "Parent Idea",
"urlName": "parent-idea"
},
"source": {
"name": "canny",
"type": "web"
},
"status": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Under Review",
"type": "Active",
"urlName": "under-review"
},
"title": "An awesome feature request",
"updatedAt": "2026-11-01T04:00:00.000Z",
"urlName": "an-awesome-feature-request"
}]
}Merge idea
Merges one idea into another idea.
apiKeystringrequiredmergeIdeaIDstringrequiredintoIdeaIDstringrequiredmergerIDstringrequiredReturns
Returns success if the idea was merged.
https://canny.io/ api/ v1/ ideas/ merge$ curl https://canny.io/api/v1/ideas/merge -X POST \
-d apiKey=YOUR_API_KEY \
-d mergeIdeaID=6a2889c586d7b8843bf4cf05 \
-d intoIdeaID=6a2889c586d7b8843bf4cf06 \
-d mergerID=6a2889c586d7b8843bf4cf07success{"error":"invalid mergeIdeaID"}Retrieve idea
Retrieves the details of an existing idea, specified by its id or urlName.
apiKeystringrequiredidstringoptionalurlNamestringoptionalReturns
Returns an idea object, if a valid id or urlName was supplied.
https://canny.io/ api/ v1/ ideas/ retrieve$ curl https://canny.io/api/v1/ideas/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf05{
"id": "6a2889c586d7b8843bf4cf05",
"childCount": 0,
"created": "2026-11-01T04:00:00.000Z",
"description": "Test idea description",
"author": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"owner": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"group": {
"id": "6a2889c586d7b8843bf4cf02",
"name": "Feature Requests",
"description": "Feature requests are ideas for new features or improvements to the product.",
"urlName": "feature-requests"
},
"parent": {
"id": "6a2889c586d7b8843bf4cf04",
"title": "Parent Idea",
"urlName": "parent-idea"
},
"source": {
"name": "canny",
"type": "web"
},
"status": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Under Review",
"type": "Active",
"urlName": "under-review"
},
"title": "An awesome feature request",
"updatedAt": "2026-11-01T04:00:00.000Z",
"urlName": "an-awesome-feature-request"
}Delete idea
Deletes an existing idea.
apiKeystringrequiredidstringrequiredReturns
Returns success if the idea was deleted successfully.
https://canny.io/ api/ v1/ ideas/ delete$ curl https://canny.io/api/v1/ideas/delete -X POST -d '{
"apiKey": "YOUR_API_KEY",
"id": "6a2889c586d7b8843bf4cf05"' \
-H "Content-Type: application/json"success{"error":"invalid idea id"}Insights
Insights are pieces of feedback, context, or information associated with ideas. They can be created manually or automatically from comments, votes, or other sources.
The Insights API allows you to list insights for your company.
The insight object
idstringauthorUser object | nullcompanyCompany object | nullcreatedstringideaIDstringprioritystring | nullsourceSource objecturlstring | nullusersUser object[]valuestring{
"id": "6a2889c586d7b8843bf4cf02",
"author": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"company": {
"monthlySpend": 1000,
"name": "Company Name",
"id": "1234567890",
"urlName": "company-name"
},
"created": "2026-11-01T04:00:00.000Z",
"ideaID": "6a2889c586d7b8843bf4cf04",
"priority": "high",
"source": {
"name": "ui",
"type": "manual"
},
"url": null,
"users": [{
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
}],
"value": "This is an important insight about the feature."
}List insights
Returns a paginated list of insights for your company.
apiKeystringrequiredcursorstringoptionalideaIDstringoptionallimitnumberoptionalReturns
A dictionary with an "items" array of insight objects, a "hasNextPage" boolean indicating if more results are available, and a "cursor" string to fetch the next page when hasNextPage is true.
https://canny.io/ api/ v1/ insights/ list$ curl https://canny.io/api/v1/insights/list -X POST \
-d apiKey=YOUR_API_KEY \
-d limit=10{
"cursor": "eyJhZnRlciI6eyJfaWQiOiI1NTNjM2VmOGI4Y2RjZD...",
"hasNextPage": true,
"items": [{
"id": "6a2889c586d7b8843bf4cf02",
"author": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"company": {
"monthlySpend": 1000,
"name": "Company Name",
"id": "1234567890",
"urlName": "company-name"
},
"created": "2026-11-01T04:00:00.000Z",
"ideaID": "6a2889c586d7b8843bf4cf04",
"priority": "high",
"source": {
"name": "ui",
"type": "manual"
},
"url": null,
"users": [{
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
}],
"value": "This is an important insight about the feature."
}]
}Retrieve insight
Retrieves the details of an existing insight. You must specify the insight's unique identifier from Canny.
apiKeystringrequiredidstringrequiredReturns
Returns an insight object, if a valid identifier was supplied.
https://canny.io/ api/ v1/ insights/ retrieve$ curl https://canny.io/api/v1/insights/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf02{
"id": "6a2889c586d7b8843bf4cf02",
"author": {
"id": "6a2889c586d7b8843bf4cf03",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
},
"company": {
"monthlySpend": 1000,
"name": "Company Name",
"id": "1234567890",
"urlName": "company-name"
},
"created": "2026-11-01T04:00:00.000Z",
"ideaID": "6a2889c586d7b8843bf4cf04",
"priority": "undefined",
"source": {
"name": "ui",
"type": "manual"
},
"url": "https://example.com/insight",
"users": [{
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "john@example.com",
"isAdmin": false,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "1234"
}],
"value": "This is an important insight about the feature."
}Opportunities
An opportunity represents a potential customer, synced in from Salesforce or Hubspot. The API allows you to fetch the list of opportunities linked to posts in Canny.
The opportunity object
idstringclosedbooleanideaIDsarraynamestringpostIDsarraysalesforce OpportunityIDstringstagestring | nullvaluenumberwonboolean{
"id": "61a942ed07bfe27b60109ee0",
"closed": true,
"ideaIDs": ["61a942ed07bfe27b60109eaf", "61a942ed07bfe27b60109ebc"],
"name": "Opportunity Name",
"postIDs": ["61a942ed07bfe27b60109ea3", "61a942ed07bfe27b60109eb4"],
"salesforceOpportunityID": "0063k00000zx6BkAAI",
"stage": "Closed Won",
"value": 1999.99,
"won": true
}List opportunties
Returns a list of opportunities linked to posts in Canny.
apiKeystringrequiredlimitnumberoptionalskipnumberoptionalReturns
A dictionary with an "opportunities" property that contains an array of opportunity objects. There's also a "hasMore" property that specifies whether this query returns more opportunities than the limit.
https://canny.io/ api/ v1/ opportunities/ list$ curl https://canny.io/api/v1/opportunities/list -X POST \
-d apiKey=YOUR_API_KEY{
"hasMore": false,
"opportunities": [{
"id": "61a942ed07bfe27b60109ee0",
"closed": true,
"ideaIDs": ["61a942ed07bfe27b60109ea3", "61a942ed07bfe27b60109eb4"],
"name": "Opportunity Name",
"postIDs": ["61a942ed07bfe27b60109eaf", "61a942ed07bfe27b60109ebc"],
"salesforceOpportunityID": "0063k00000zx6BkAAI",
"stage": "Closed Won",
"value": 1999.99,
"won": true
}]
}Posts
A post is an object that represents an idea posted to a board. They are always associated with a user and a board. Users can vote on them. The API allows you to fetch a specific post, or a list of posts for a board.
The post object
idstringauthorUser object | nullboardBoard objectbyUser object | nullcategoryCategory object | nullcommentCountnumbercreatedstringclickup.linkedTasksarraycustomFieldsarraydetailsstringetastring | nullimageURLsarrayideaIdea object | nulljira.linkedIssuesarraylinear.linkedIssueIDsarrayownerUser object | nullroadmapsarrayscorenumberstatusstringstatusChangedAtstringtagsarraytitlestringurlstring{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-20T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": true,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"id": "6a2889c586d7b8843bf4cf01",
"created": "2017-07-15T22:11:00.000Z",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "6a2889c586d7b8843bf4cf19",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"parentID": null,
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 10,
"created": "2017-08-03T22:11:00.000Z",
"clickup": {
"linkedTasks": [{
"id": "123",
"linkID": "2334jdsai23234io22",
"name": "Clickup issue",
"postID": "6a2889c586d7b8843bf4cf05",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"customFields": [
{
"id": "6a2889c586d7b8843bf4cf20",
"name": "Estimated effort",
"value": "3 weeks"
}
],
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"idea": null,
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"owner": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-20T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": true,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"score": 72,
"status": "in progress",
"tags": [{
"id": "6a2889c586d7b8843bf4cf0d",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
}Retrieve post
Retrieves the details of an existing post, specified by its id or urlName.
apiKeystringrequiredboardIDstringoptionalidstringoptionalurlNamestringoptionalReturns
Returns a post object, if a valid id was supplied.
https://canny.io/ api/ v1/ posts/ retrieve$ curl https://canny.io/api/v1/posts/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf05{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": true,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "6a2889c586d7b8843bf4cf19",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"parentID": null,
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"changeComment": {
"value": "The status has changed!",
"imageURLs": ["https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b2.png"]
},
"clickup": {
"linkedTasks": [{
"id": "123",
"linkID": "2334jdsai23234io22",
"name": "Clickup issue",
"postID": "6a2889c586d7b8843bf4cf05",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2026-11-01T04:00:00.000Z",
"customFields": [{
"id": "6a2889c586d7b8843bf4cf0e",
"name": "priority",
"value": "high",
}],
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"mergeHistory":[{
"created":"2026-11-01T04:00:00.000Z",
"post": {
"created":"2026-11-01T04:00:00.000Z",
"details":"Awesome feature post details",
"id": "6a2889c586d7b8843bf4cf14",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"owner": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": true,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"score": 72,
"status": "in progress",
"statusChangedAt": "2026-11-01T04:00:00.000Z",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
}List posts
Returns a list of posts. Include parameters to specify board, pagination, filtering, and sorting.
apiKeystringrequiredboardIDstringoptionalauthorIDstringoptionalcompanyIDstringoptionaltagIDsarrayoptionallimitnumberoptionalsearchstringoptionalskipnumberoptionalsortstringoptionalstatusstringoptionalReturns
A dictionary with a "posts" property that contains an array of post objects. There's also a "hasMore" property that specifies whether this query returns more posts than the limit.
https://canny.io/ api/ v1/ posts/ list$ curl https://canny.io/api/v1/posts/list -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=6a2889c586d7b8843bf4cf01{
"hasMore": true,
"posts": [{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "6a2889c586d7b8843bf4cf19",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"parentID": null,
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"clickup": {
"linkedTasks": [{
"id": "123",
"linkID": "2334jdsai23234io22",
"name": "Clickup issue",
"postID": "6a2889c586d7b8843bf4cf05",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2026-11-01T04:00:00.000Z",
"customFields": [{
"id": "6a2889c586d7b8843bf4cf0e",
"name": "priority",
"value": "high",
}],
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"mergeHistory":[{
"created":"2026-11-01T04:00:00.000Z",
"post": {
"created":"2026-11-01T04:00:00.000Z",
"details":"Awesome feature post details",
"id": "6a2889c586d7b8843bf4cf14",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"owner": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": true,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"score": 72,
"status": "in progress",
"statusChangedAt": "2026-11-01T04:00:00.000Z",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
}]
}Create post
Creates a new post.
You may also want to use the Create or update user endpoint to make sure the post author's account exists (and fetch their id).
apiKeystringrequiredauthorIDstringrequiredboardIDstringrequiredbyIDstringoptionalcategoryIDstringoptionalcustomFieldsobjectoptionaldetailsstringrequiredetastringoptionaletaPublicbooleanoptionaltitlestringrequiredownerIDstringoptionalimageURLsarrayoptionalcreatedAtstringoptionalReturns
Upon success, returns an object with two keys: id and url.
https://canny.io/ api/ v1/ posts/ create$ curl https://canny.io/api/v1/posts/create -X POST -d '{
"apiKey": "YOUR_API_KEY",
"authorID": "6a2889c586d7b8843bf4cf05",
"boardID": "6a2889c586d7b8843bf4cf01",
"customFields": {
"number": 12,
"string": "value"
},
"details": "This is the post's details",
"title": "Post Title"}' \
-H "Content-Type: application/json"{
"id": "6a2889c586d7b8843bf4cf09",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
}Change board
Moves a post to another board.
apiKeystringrequiredboardIDstringrequiredpostIDstringrequiredReturns
Returns success if the post was moved.
https://canny.io/ api/ v1/ posts/ change_board$ curl https://canny.io/api/v1/posts/change_board -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=6a2889c586d7b8843bf4cf01 \
-d postID=6a2889c586d7b8843bf4cf05success{"error":"invalid postID"}Change post category
Changes a post's category specified by its id.
apiKeystringrequiredcategoryIDstringoptionalpostIDstringrequiredReturns
Returns the updated post if the post's category was successfully changed.
https://canny.io/ api/ v1/ posts/ change_category$ curl https://canny.io/api/v1/posts/change_category -X POST \
-d apiKey=YOUR_API_KEY \
-d categoryID=6a2889c586d7b8843bf4cf1a \
-d postID=6a2889c586d7b8843bf4cf05{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "6a2889c586d7b8843bf4cf19",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"parentID": null,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"changeComment": {
"value": "The status has changed!",
"imageURLs": ["https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b2.png"]
},
"clickup": {
"linkedTasks": [{
"id": "123",
"linkID": "2334jdsai23234io22",
"name": "Clickup issue",
"postID": "6a2889c586d7b8843bf4cf05",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2017-08-22T13:32:00.000Z",
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "6a2889c586d7b8843bf4cf14",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
}{"error":"invalid post id"}Change post status
Changes a post's status (eg. to 'planned'), specified by its id.
apiKeystringrequiredchangerIDstringrequiredpostIDstringrequiredshouldNotifyVotersbooleanrequiredstatusstringrequiredcommentValuestringoptionalcommentImageURLsarrayoptionalReturns
Returns the updated post if the post's status was successfully changed.
https://canny.io/ api/ v1/ posts/ change_status$ curl https://canny.io/api/v1/posts/change_status -X POST \
-d apiKey=YOUR_API_KEY \
-d changerID=6a2889c586d7b8843bf4cf07 \
-d postID=6a2889c586d7b8843bf4cf05 \
-d shouldNotifyVoters=true \
-d status="in progress"{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "6a2889c586d7b8843bf4cf19",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"parentID": null,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"changeComment": {
"value": "The status has changed!",
"imageURLs": ["https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b2.png"]
},
"commentCount": 10,
"created": "2017-08-22T13:32:00.000Z",
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "6a2889c586d7b8843bf4cf14",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
}{"error":"invalid post id"}Merge post
Merges one post into another post.
apiKeystringrequiredmergePostIDstringrequiredintoPostIDstringrequiredmergerIDstringrequiredReturns
Returns success if the post was merged.
https://canny.io/ api/ v1/ posts/ merge$ curl https://canny.io/api/v1/posts/merge -X POST \
-d apiKey=YOUR_API_KEY \
-d mergePostID=6a2889c586d7b8843bf4cf05 \
-d intoPostID=6a2889c586d7b8843bf4cf06 \
-d mergerID=6a2889c586d7b8843bf4cf07success{"error":"invalid mergePostID"}Add post tag
Adds a tag to a post. Both post and tag are specified by their unique id.
apiKeystringrequiredpostIDstringrequiredtagIDstringrequiredReturns
Returns the updated post if the tag was successfully added.
https://canny.io/ api/ v1/ posts/ add_tag$ curl https://canny.io/api/v1/posts/add_tag -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf05
-d tagID=6a2889c586d7b8843bf4cf0b{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "6a2889c586d7b8843bf4cf19",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"parentID": null,
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"changeComment": {
"value": "The status has changed!",
"imageURLs": ["https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b2.png"]
},
"clickup": {
"linkedTasks": [{
"id": "123",
"linkID": "2334jdsai23234io22",
"name": "Clickup issue",
"postID": "6a2889c586d7b8843bf4cf05",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2017-08-22T13:32:00.000Z",
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "6a2889c586d7b8843bf4cf14",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}, {
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2018-04-20T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf0b",
"name": "Example Tag",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=example-tag"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
}{"error":"invalid post id"}Remove post tag
Removes a tag from a post. Both post and tag are specified by their unique id.
apiKeystringrequiredpostIDstringrequiredtagIDstringrequiredReturns
Returns the updated post if the tag was successfully remove.
https://canny.io/ api/ v1/ posts/ remove_tag$ curl https://canny.io/api/v1/posts/remove_tag -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf05
-d tagID=6a2889c586d7b8843bf4cf0b{
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "6a2889c586d7b8843bf4cf19",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"parentID": null,
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"changeComment": {
"value": "The status has changed!",
"imageURLs": ["https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b2.png"]
},
"clickup": {
"linkedTasks": [{
"id": "123",
"linkID": "2334jdsai23234io22",
"name": "Clickup issue",
"postID": "6a2889c586d7b8843bf4cf05",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2017-08-22T13:32:00.000Z",
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "6a2889c586d7b8843bf4cf14",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
}{"error":"invalid post id"}Update post
Updates an existing post.
apiKeystringrequiredpostIDstringrequiredchangerIDstringoptionalcustomFieldsobjectoptionaldetailsstringoptionaletastring | nulloptionaletaPublicbooleanoptionalimageURLsarrayoptionalownerIDstring | nulloptionaltitlestringoptionalReturns
Returns "success" if the post was updated successfully.
https://canny.io/ api/ v1/ posts/ update$ curl https://canny.io/api/v1/posts/update -X POST -d '{
"apiKey": "YOUR_API_KEY",
"postID": "6a2889c586d7b8843bf4cf05",
"customFields": {
"number": 12,
"string": "value"
},
"details": "Updated post details",
"title": "Updated post title",
"eta": "01/2025",
"imageURLs": ["https://picsum.photos/200"],
"etaPublic": true}' \
-H "Content-Type: application/json"successDelete post
Deletes an existing post.
apiKeystringrequiredpostIDstringrequiredReturns
Returns "success" if the post was deleted successfully.
https://canny.io/ api/ v1/ posts/ delete$ curl https://canny.io/api/v1/posts/delete -X POST -d '{
"apiKey": "YOUR_API_KEY",
"postID": "6a2889c586d7b8843bf4cf05"' \
-H "Content-Type: application/json"successLink a Jira issue to a post
Links a Jira issue to a Canny post. Requires the Jira integration to be installed and configured.
apiKeystringrequiredpostIDstringrequiredissueKeystringrequiredReturns
Returns "success" if the post was linked successfully.
https://canny.io/ api/ v1/ posts/ link_jira$ curl https://canny.io/api/v1/posts/link_jira -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf05 \
-d issueKey=PROJ-123successUnlink a Jira issue from a post
Unlinks a Jira issue from a Canny post. Requires the Jira integration to be installed and configured.
apiKeystringrequiredpostIDstringrequiredissueKeystringrequiredReturns
Returns "success" if the post was unlinked successfully.
https://canny.io/ api/ v1/ posts/ unlink_jira$ curl https://canny.io/api/v1/posts/unlink_jira -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf05 \
-d issueKey=PROJ-123successRoadmaps
A roadmap is a collection of posts. Posts can be associated with multiple roadmaps.
Roadmap data is exposed via API endpoints that fetch post data.
The roadmap object
idstringarchivedbooleancreatedstringnamestringpostCountnumberurlstring{
"id": "6a2889c586d7b8843bf4cf0b",
"archived": false,
"created": "2024-09-30T13:32:01.000Z",
"name": "Example Roadmap",
"postCount": 12,
"url": "https://your-company.canny.io/admin/roadmap/example-roadmap"
}Status Changes
Posts can be assigned a status: open, under review, planned, in progress, complete, or closed.
Our API allows you to list status changes, sorted by recency.
The status change object
idstringchangeCommentComment object | nullchangerUser object | nullcreatedstringpostPost objectstatusstring{
"changeComment": {
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"value": "This is the status change comment value"
},
"changer": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf0b",
"post": {
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"changeComment": {
"value": "The status has changed!",
"imageURLs": ["https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b2.png"]
},
"clickup": {
"linkedTasks": [{
"id": "123",
"linkID": "2334jdsai23234io22",
"name": "Clickup issue",
"postID": "6a2889c586d7b8843bf4cf05",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2017-08-22T13:32:00.000Z",
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "6a2889c586d7b8843bf4cf14",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
},
"status": "in progress"
}List status changes
Returns a list of status changes. Include parameters to specify board and pagination. Sorted by newest.
apiKeystringrequiredboardIDstringoptionalcursorstringoptionallimitnumberoptionalReturns
A dictionary with an "items" property that contains an array of status change objects. There's also a "hasNextPage" property that specifies whether there are more status changes available, and a "cursor" property that can be used to fetch the next page of results.
https://canny.io/ api/ v2/ status_changes/ list$ curl https://canny.io/api/v2/status_changes/list -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=6a2889c586d7b8843bf4cf01{
"cursor": "eyJhZnRlciI6eyJfaWQiOiI1NTNjM2VmOGI4Y2RjZD...",
"hasNextPage": false,
"items": [{
"changeComment": {
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"value": "The status has changed!"
},
"changer": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf0b",
"post": {
"category": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"parentID": null,
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 10,
"details": "Test post details",
"id": "6a2889c586d7b8843bf4cf05",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}],
"linkedIssueIDs": ["123"]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"]
},
"score": 72,
"status": "in progress",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/an-awesome-feature-request"
},
"status": "in progress"
}]
}Tags
Posts can be assigned multiple tags. Each tag is for a specific board, not company-wide.
Our API allows you to create, list, and retrieve tags. You can also tag and un-tag posts.
The tag object
idstringboardBoard objectcreatedstringnamestringpostCountnumberurlstring{
"id": "6a2889c586d7b8843bf4cf0b",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"name": "Example Tag Name",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?tag=example-tag-name"
}Retrieve tag
Retrieves the details of an existing tag, specified by its id.
apiKeystringrequiredidstringrequiredReturns
Returns a tag object, if a valid id was supplied.
https://canny.io/ api/ v1/ tags/ retrieve$ curl https://canny.io/api/v1/tags/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf0b{
"id": "6a2889c586d7b8843bf4cf0b",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"name": "Example Tag Name",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?tag=example-tag-name"
}List tags
Returns a list of tags. Include parameters to specify board and pagination. Sorted by newest.
apiKeystringrequiredboardIDstringoptionallimitnumberoptionalskipnumberoptionalReturns
A dictionary with a "tags" property that contains an array of tag objects. There's also a "hasMore" property that specifies whether this query returns more tags than the limit.
https://canny.io/ api/ v1/ tags/ list$ curl https://canny.io/api/v1/tags/list -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=6a2889c586d7b8843bf4cf01{
"hasMore": false,
"tags": [{
"id": "6a2889c586d7b8843bf4cf0b",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"name": "Example Tag Name",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?tag=example-tag-name"
}]
}Create tag
Creates a new tag.
apiKeystringrequiredboardIDstringrequirednamestringrequiredReturns
Returns the tag object, if it was successfully created or already exists.
https://canny.io/ api/ v1/ tags/ create$ curl https://canny.io/api/v1/tags/create -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=6a2889c586d7b8843bf4cf12 \
-d name="New Tag"{
"id": "6a2889c586d7b8843bf4cf0b",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"name": "Example Tag Name",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?tag=example-tag-name"
}Users
Users can create posts, votes, and comments. Admins also have user accounts. The API allows you to fetch a specific user.
The user object
idstringaliasstring | nullavatarURLstring | nullcompaniesarraycreatedstringcustomFieldsobject | nullemailstring | nullisAdminbooleanlastActivitystring | nullnamestringurlstringuserIDstring | null{
"id": "6a2889c586d7b8843bf4cf07",
"alias": "Green Fish",
"avatarURL": "https://canny.io/images/a3db0133d1e7d9122832b67b2c4caaaa.jpg",
"companies": [{
"created": "2020-01-23T04:56:07.890Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"id": "company123",
"monthlySpend": 500.00,
"name": "company name"
}],
"created": "2026-11-01T04:00:00.000Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "test@test.test",
"isAdmin": false,
"lastActivity": "2026-11-01T04:00:00.000Z",
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
}List users
List the end-users within your workspace.
apiKeystringrequiredlimitnumberoptionalcursorstringoptionalReturns
Returns an array of users.
https://canny.io/ api/ v2/ users/ list$ curl https://canny.io/api/v2/users/list -X POST \
-d apiKey=YOUR_API_KEY \
-d limit=100 \
-d cursor=NTUzYzNlZjhiOGNkY2QxNTAxYmExMjNhXzIwMjUtMDItMDRUMTY6NDA6MDcuNTQxWl8x
{
"hasNextPage": true,
"cursor": "NTUzYzNlZjhiOGNkY2QxNTAxYmExMjNhXzIwMjUtMDItMDRUMTY6NDA6MDcuNTQxWl8x",
"users": [{
"id": "6a2889c586d7b8843bf4cf07",
"alias": "Green Fish",
"avatarURL": "https://canny.io/images/a3db0133d1e7d9122832b67b2c4caaaa.jpg",
"created": "2026-11-01T04:00:00.000Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "test@test.test",
"isAdmin": false,
"lastActivity": "2026-11-01T04:00:00.000Z",
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
}]
}Retrieve user
Retrieves the details of an existing user. You must specify exactly one of: their Canny id, their id in your application, or their email. These fields are all unique per user.
You can only retrieve them based on their id in your application if the user was authenticated via single sign-on or created via API.
apiKeystringrequiredemailstringoptionalidstringoptionaluserIDstringoptionalReturns
Returns a user object, if a valid identifier was supplied.
https://canny.io/ api/ v1/ users/ retrieve$ curl https://canny.io/api/v1/users/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf07$ curl https://canny.io/api/v1/users/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d userID=1234$ curl https://canny.io/api/v1/users/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d email="test@test.test"{
"id": "6a2889c586d7b8843bf4cf07",
"alias": "Green Fish",
"avatarURL": "https://canny.io/images/a3db0133d1e7d9122832b67b2c4caaaa.jpg",
"created": "2026-11-01T04:00:00.000Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "test@test.test",
"isAdmin": false,
"lastActivity": "2026-11-01T04:00:00.000Z",
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
}Create or update user
If the user does not exist, one is created, and its id is returned. If the user does exist, they will be updated with the data supplied.
Why is this endpoint useful? If you're going to use an object creation API endpoint (such as create post), you may have to create the author's account before creating the post.
apiKeystringrequiredaliasstringoptionalavatarURLstringoptionalcompaniesarrayoptionalDefines the list of companies the user is associated with. To associate a user with a company, the user must have a UserID. Verify the UserID using the retrieve user endpoint.
Omitting a company that the user is currently associated with will not disassociate the user from that company. To disassociate a user from a company, use the remove user from a company endpoint.
Each company needs a name, up to 100 characters. It can't contain a URL or slashes, or be a reserved word like "Feedback" or "Roadmap". If you include a domain, use a bare domain like "acme.com".
createddateoptionalcustomFieldsobjectoptionalemailstringoptionalidstringoptionalThe user's unique identifier in Canny. This can be found through the list users endpoint.
namestringrequireduserIDstringoptionalReturns
Upon success, returns an object with a single key: id.
You can then use this id in object creation API endpoints such as for creating posts.
https://canny.io/ api/ v1/ users/ create_or_updatehttps://canny.io/api/v1/users/find_or_create (deprecated)$ curl https://canny.io/api/v1/users/create_or_update -X POST -d '{
"apiKey": "YOUR_API_KEY",
"alias": "Green Fish",
"companies": [{
"created": "2026-11-01T04:00:00.000Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"domain": "acme.com",
"id": "company123",
"monthlySpend": 500.00,
"name": "company name"
}],
"created": "2026-11-01T04:00:00.000Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "sally@netflix.com",
"name": "Sally Doe",
"userID": "1234-5678"}' \
-H "Content-Type: application/json"{
"id": "6a2889c586d7b8843bf4cf07",
}Delete user
Deletes a user. Also deletes all of their comments and votes.
If their posts have other comments/votes, then they'll be removed as an author. If there are no other comments/votes, the post will be removed.
apiKeystringrequiredidstringrequiredReturns
Returns "success" if the user was successfully deleted.
https://canny.io/ api/ v1/ users/ delete$ curl https://canny.io/api/v1/users/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d userID=6a2889c586d7b8843bf4cf0c"successRemove user from a company
Removes the user from a company that they were previously associated with.
Why is this endpoint useful? If a user of your application has moved from one organization to another or if a user is no longer a part of an organization.
Please note that removing a user from a company will result in their votes no longer being associated with the company's spend.
apiKeystringrequiredcompanyIDstringrequiredidstringrequiredThe unique identifier of the user. This can be found through the Retrieve User endpoint.
Returns
Returns "success" if the user was removed. Otherwise an error describing the issue with your request.
https://canny.io/ api/ v1/ users/ remove_user_from_company$ curl https://canny.io/api/v1/users/remove_user_from_company -X POST -d '{
"apiKey": "YOUR_API_KEY",
"companyID": "company1",
"id": "6a2889c586d7b8843bf4cf07"}' \
-H "Content-Type: application/json""success"Votes
Users can vote on posts. Admins can also vote on behalf of users. Vote objects are always associated with a post and a voter. The API allows you to fetch a specific vote, or a list of votes associated with a post.
The vote object
idstringboardBoard objectbyUser object | nullcreatedstringpostPost objectvoterUser objectvotePrioritystringzendeskTicketobject | null{
"id": "6a2889c586d7b8843bf4cf08",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": null,
"created": "2017-08-30T13:32:01.000Z",
"post": {
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf0d",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
},
"voter": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-08-30T13:32:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"zendeskTicket": {
"url": "https://your-company.zendesk.com/api/v2/tickets/2.json",
"id": 2,
"created": "2018-12-14T19:20:25Z",
"subject": "Ticket subject",
"description": "Ticket description",
},
"votePriority": "No priority",
}Retrieve vote
Retrieves the details of an existing vote, specified by its id.
apiKeystringrequiredidstringrequiredReturns
Returns a vote object, if a valid id was supplied.
https://canny.io/ api/ v1/ votes/ retrieve$ curl https://canny.io/api/v1/votes/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=6a2889c586d7b8843bf4cf08{
"id": "6a2889c586d7b8843bf4cf08",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "6a2889c586d7b8843bf4cf12",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": null,
"created": "2017-08-30T13:32:01.000Z",
"post": {
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"eta": "February 2020",
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"],
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
},
"voter": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-08-30T13:32:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"votePriority": "Important",
}List votes
Returns a list of votes. Include parameters to specify post, board, and pagination. Sorted by newest.
apiKeystringrequiredboardIDstringoptionalcompanyIDstringoptionalcursorstringoptionallimitnumberoptionalpostIDstringoptionaluserIDstringoptionalReturns
A dictionary with an "items" property that contains an array of vote objects. There's also a "hasNextPage" property that specifies whether there are more votes available, and a "cursor" property that can be used to fetch the next page of results.
https://canny.io/ api/ v2/ votes/ list$ curl https://canny.io/api/v2/votes/list -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf0f{
"cursor": "eyJhZnRlciI6eyJfaWQiOiI1NTNjM2VmOGI4Y2RjZD...",
"hasNextPage": true,
"items": [{
"id": "6a2889c586d7b8843bf4cf08",
"board": {
"created": "2026-11-01T04:00:00.000Z",
"id": "6a2889c586d7b8843bf4cf01",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": null,
"created": "2026-11-01T04:00:00.000Z",
"post": {
"category": {
"id": "6a2889c586d7b8843bf4cf0d",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "6a2889c586d7b8843bf4cf13",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}],
},
"linear": {
"linkedIssueIDs": ["ID-123", "ID-345"]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "6a2889c586d7b8843bf4cf10",
"name": "iOS",
"postCount": 15,
"url": "https://your-company.canny.io/admin/board/feature-requests?tags=ios"
}],
"title": "post-title",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
},
"voter": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2026-11-01T04:00:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"votePriority": "No priority",
"zendeskTicket": {
"id": "2",
"created": "2018-12-14T19:20:25Z",
"subject": "Ticket subject",
"description": "Ticket description",
"url": "https://your-company.zendesk.com/api/v2/tickets/2.json"
}
}]
}Create vote
Creates a new vote.
You may also want to use the Create or update user endpoint to make sure the voter's account exists (and fetch their id).
apiKeystringrequiredbyIDstringoptionalcreatedAtstringoptionalpostIDstringrequiredvoterIDstringrequiredvotePrioritystringoptionalReturns
Returns "success" if the vote was successfully created or already exists.
https://canny.io/ api/ v1/ votes/ create$ curl https://canny.io/api/v1/votes/create -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf09 \
-d voterID=6a2889c586d7b8843bf4cf05successDelete vote
Deletes a vote.
apiKeystringrequiredpostIDstringrequiredvoterIDstringrequiredReturns
Returns "success" if the vote was successfully deleted, or already doesn't exist.
https://canny.io/ api/ v1/ votes/ delete$ curl https://canny.io/api/v1/votes/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=6a2889c586d7b8843bf4cf09 \
-d voterID=6a2889c586d7b8843bf4cf05successWebhooks
By setting up webhooks, your server will be notified of Canny events as they happen. For example, if a user creates a new post, we would send a request to your server to let you know.
Every request is signed, so you can confirm it was sent by Canny. Once you add a webhook, your signing secret appears on the same settings page, and Webhook signatures explains how to verify a request.
The event object
createdstringobjectobjectobjectTypestringtypestring{
"created": "2017-07-15T22:11:00.000Z",
"object": {
"id": "6a2889c586d7b8843bf4cf05",
"author": {
"id": "6a2889c586d7b8843bf4cf07",
"created": "2017-07-15T22:11:00.000Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"id": "6a2889c586d7b8843bf4cf01",
"created": "2017-07-15T22:11:00.000Z",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"commentCount": 10,
"created": "2017-07-15T22:11:00.000Z",
"details": "Test post details",
"eta": "February 2020",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"score": 72,
"status": "in progress",
"title": "An awesome feature request",
"url": "https://your-company.canny.io/admin/board/feature-requests/p/post-title"
},
"objectType": "post",
"type": "post.created"
}Event types
This is a list of all types of events we send.
post.createdpost.editedpost.deletedpost.jira_issue_linkedpost.jira_issue_unlinkedpost.tag_addedpost.tag_removedpost.status_changedcomment.createdcomment.editedcomment.deletedvote.createdvote.deletedchangelog_entry.createdchangelog_entry.publishedchangelog_entry.unpublishedchangelog_entry.deletedWebhook signatures
Canny signs every webhook following the Standard Webhooks specification, so you can confirm a request was sent by Canny and was not modified. Each request includes the following headers.
webhook-idwebhook-timestampwebhook-signatureYour signing secret is in your API settings once you have added a webhook. The easiest way to verify a request is with an official Standard Webhooks library, available for JavaScript, Python, Go, Java, C#, Ruby, PHP, Rust and Elixir. Pass it the raw request body exactly as received, before parsing it as JSON.
import { Webhook } from 'standardwebhooks';
const webhook = new Webhook('YOUR_WEBHOOK_SECRET');
// rawBody must be the exact request body, before any JSON parsing.
// Throws if the signature is invalid or the timestamp is too old.
function verify(rawBody, headers) {
return webhook.verify(rawBody, headers);
}Autopilot Feedback Processing
Autopilot is Canny's AI-powered set of tools that can detect, extract and deduplicate customer feedback. For Canny accounts with Autopilot, we offer direct access to Autopilot with an API that queues text input for processing.
Each API request uses one Autopilot credit. Click here to learn more about Autopilot and credits.
Enqueue feedback
Adds an item of feedback to the queue. During the next sync, Autopilot will extract any feature requests and identify any duplicates. You can see the results when they are done processing.
When in manual mode, the Autopilot inbox has a limit of 100 items. If you exceed this limit, you won't be able to enqueue any more items until you process them. Enabling automated mode is recommended to skip this limit, and view an audit log of the actions taken by Autopilot.
apiKeystringrequiredpayloadobjectrequiredpayload.idstringrequiredpayload.authorIDstringrequiredpayload.textstringrequiredpayload.sourceURLstringoptionalpayload.sourceTypestringoptionaltypestringrequiredReturns
Returns "success" if the payload was enqueued. Otherwise an error describing the issue with your request.
https://canny.io/ api/ v1/ ai/ enqueue$ curl https://canny.io/api/v1/ai/enqueue -X POST -d '{
"apiKey": "YOUR_API_KEY",
"payload": {
"id": "conversationID",
"authorID": "6a2889c586d7b8843bf4cf07",
"sourceURL": "https://twitter.com/cannyHQ/status/1728150249263218855",
"sourceType": "twitter",
"text": "I love this product! No feature requests, just wanted to say thanks!"
},
"type": "conversation"
}' \
-H "Content-Type: application/json""success"