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. This key is This key is secret! 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.
Example request:
$ curl https://canny.io/api/v1/boards/list \
-d apiKey=YOUR_API_KEY
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
Attributes
id
string
A unique identifier for the board.
created
string
Time at which the board was created, in ISO 8601 format.
isPrivate
boolean
Whether or not the board is set as private in the administrative settings.
name
string
The board's name.
postCount
number
The number of non-deleted posts associated with the board. This number includes posts that are marked as closed or complete.
privateComments
boolean
Whether or not comments left on posts can be viewed by other end-users.
url
string
The URL to the board's page.
Example board object:
{
"id": "553c3ef8b8cdcd1501ba1234",
"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.
Arguments
apiKey
string
Your secret API key.
id
string
The board's unique identifier.
Returns
Returns a board object, if a valid id was supplied.
Endpoint
https://canny.io/api/v1/boards/retrieve
Method
POST
Example Request
$ curl https://canny.io/api/v1/boards/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=553c3ef8b8cdcd1501ba1234
Example Response
{
"id": "553c3ef8b8cdcd1501ba1234",
"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.
Arguments
apiKey
string
Your secret API key.
Returns
A dictionary with a "boards" property that contains an array of board objects.
Endpoint
https://canny.io/api/v1/boards/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/boards/list -X POST \
-d apiKey=YOUR_API_KEY
Example Response
{
"boards": [{
"id": "553c3ef8b8cdcd1501ba1234",
"created": "2024-12-21T04:47:46.618Z",
"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": "553c3ef8b8cdcd1501ba1238",
"created": "2024-12-21T04:47:46.618Z",
"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
Attributes
id
string
A unique identifier for the category.
board
Board object
The board this category is associated with.
created
string
Time at which the category was created, in ISO 8601 format.
name
string
The name of the category.
parentID
string
The id of the parent category. If this category is not a sub category, this field will be null.
postCount
number
The number of posts that have been assigned this category.
url
string
The URL to the board, filtered to just posts that have been assigned this category.
Example category object:
{
"id": "553c3ef8b8cdcd1501ba12bb",
"board": {
"created": "2024-12-21T04:47:46.619Z",
"id": "553c3ef8b8cdcd1501ba4400",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2024-12-21T04:47:46.619Z",
"name": "Example Category Name",
"parentID": "552c3ef8b8cdcd1501ba12bb",
"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.
Arguments
apiKey
string
Your secret API key.
id
string
The category's unique identifier.
Returns
Returns a category object, if a valid id was supplied.
Endpoint
https://canny.io/api/v1/categories/retrieve
Method
POST
Example Request
$ curl https://canny.io/api/v1/categories/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=553c3ef8b8cdcd1501ba12bb
Example Response
{
"id": "553c3ef8b8cdcd1501ba12bb",
"board": {
"created": "2024-12-21T04:47:46.620Z",
"id": "553c3ef8b8cdcd1501ba4400",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2024-12-21T04:47:46.620Z",
"name": "Example Category Name",
"parentID": "552c3ef8b8cdcd1501ba12bb",
"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.
Arguments
apiKey
string
Your secret API key.
boardID
string (optional)
The id of the board you'd like to fetch categories for.
limit
number (optional)
The number of categories you'd like to fetch. Defaults to 10 if not specified. Max of 10000.
skip
number (optional)
The number of categories you'd like to skip before starting to fetch. Defaults to 0 if not specified.
Returns
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.
Endpoint
https://canny.io/api/v1/categories/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/categories/list -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=553c3ef8b8cdcd1501ba1234
Example Response
{
"categories": [{
"id": "553c3ef8b8cdcd1501ba12bb",
"board": {
"created": "2024-12-21T04:47:46.620Z",
"id": "553c3ef8b8cdcd1501ba4400",
"name": "Feature Requests",
"postCount": 99,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2024-12-21T04:47:46.620Z",
"name": "Example Category Name",
"parentID": "552c3ef8b8cdcd1501ba12bb",
"postCount": 12,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=example-category-name"
}],
"hasMore": false,
}
Create category
Creates a new category.
Arguments
apiKey
string
Your secret API key.
boardID
string
The id of the board you'd like to create the category for.
name
string
The name of the category. Must be between 1 and 30 characters long.
parentID
string (optional)
The id of the parent category.
subscribeAdmins
boolean
Whether or not the admins will be subscribed to the category.
Returns
Upon success, returns an object with a single key: id.
Endpoint
https://canny.io/api/v1/categories/create
Method
POST
Example Request
$ curl https://canny.io/api/v1/categories/create -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=553c3ef8b8cdcd1501ba1234 \
-d name="new category" \
-d parentID=423c3ef8b8cdcd1501ba3763 \
-d subscribeAdmins=true
Example Response
{
"id": "553c3ef8b8cdcd1501ba1240",
}
Delete category
Deletes a category If the category does not have sub categories.
Arguments
apiKey
string
Your secret API key.
categoryID
string
The unique identifier of the category.
Returns
Returns "success" if the category was successfully deleted.
Endpoint
https://canny.io/api/v1/categories/delete
Method
POST
Example Request
$ curl https://canny.io/api/v1/categories/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d categoryID=553c3ef8b8cdcd1501ba2200"
Example Response
success
Entries
A changelog is simply a list of entries. The API allows you to fetch the list of entries associated with your changelog.
The changelog entry object
Attributes
id
string
A unique identifier for the entry.
created
string
Time at which the entry was first created, in ISO 8601 format.
labels
array
The list of labels that the entry is associated with.
lastSaved
string
Time at which the entry was last updated, in ISO 8601 format.
markdownDetails
string
The markdown contents of the entry.
plaintextDetails
string
The plaintext contents of the entry, with images, videos, and links stripped.
posts
array
The list of posts this entry is linked to.
publishedAt
string
Time at which the entry was published, if it has been published.
scheduledFor
string
Time at which the entry is schedule to be published, if it is scheduled.
reactions
object
The number of reactions an entry has received.
status
string
The status of the entry, describing whether it has been published. Will be set to draft, scheduled, or published.
title
string
The title of the entry.
types
array
The list of types associated with the entry. Can include new, improved, or fixed.
url
string
The public URL to the entry page on Canny.
Example entry object:
{
"id": "553c3ef8b8cdcd1501ba123b",
"created": "2024-12-21T04:47:46.622Z",
"labels": [],
"lastSaved": "2024-12-21T04:47:46.622Z",
"markdownDetails": "# heading\n**bold**\n[link](https://canny.io)",
"plaintextDetails": "heading\nbold\nlink",
"posts": [{
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"eta": "February 2024",
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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": "2024-12-21T04:47:46.622Z",
"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 and (optionally) publishes a new changelog entry.
Arguments
apiKey
string
Your secret API key.
title
string
The title of your changelog entry.
details
string
The details of your changelog entry.
type
string (optional)
The type of your changelog entry. Can be one of "fixed", "new", and "improved".
notify
boolean (optional)
Whether to notify users by email after publishing. Default is false.
published
boolean (optional)
Whether you want to publish the changelog entry immediately or not. Default is false.
publishedOn
string (optional)
If published is set to true and you would like to set a published date in the past, in ISO 8601 format.
scheduledFor
string (optional)
The date you want the changelog entry to be published, in ISO 8601 format. This has to be in the future.
labelIDs
array (optional)
A list of labels to assign to your changelog entry. Each label must be between 1 and 30 characters long.
postIDs
array (optional)
A list of posts to link to your changelog entry.
Returns
Upon success, returns an object with a single key: id.
Endpoint
https://canny.io/api/v1/entries/create
Method
POST
Example Request
$ 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" \
Example Response
{
"id": "553c3ef8b8cdcd1501ba1240",
}
List entries
Returns a list of changelog entries. Sorted by newest.
To request translated changelog items, use the Accept-Language header in your HTTP request to specify the preferred language for the response.
- Dansk: da
- Deutsch: de
- English: en
- Español: es
- Français: fr
- Italiano: it
- Nederlands: nl
- Polski: pl
- Português (Brasil): pt
- Português (Portugal): pt-PT
- Русский: ru
- Suomi: fi
Arguments
apiKey
string
Your secret API key.
labelIDs
array (optional)
Fetch only entries with at least one of the labels in the array.
limit
number (optional)
The number of entries you'd like to fetch. Defaults to 10 if not specified.
skip
number (optional)
The number of entries you'd like to skip before starting to fetch. Defaults to 0 if not specified.
sort
string (optional)
The order in which the entries should be fetched. Options include: "created", "lastSaved", "nonPublishedFirst", "publishedAt". Defaults to "nonPublishedFirst" if not specified.
type
string (optional)
The type of entries to fetch. Value can be "new", "improved", or "fixed".
Returns
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.
Endpoint
https://canny.io/api/v1/entries/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/entries/list -X POST \
-d apiKey=YOUR_API_KEY
Example Response
{
"hasMore": false,
"entries": [{
"id": "553c3ef8b8cdcd1501ba123b",
"created": "2024-12-21T04:47:46.625Z",
"labels": [{
"id": "553c3ef8b8cdcd1501ba8761",
"created": "2024-12-21T04:47:46.625Z",
"entryCount": 4,
"name": "Feature",
"url": "https://your-company.canny.io/admin/changelog?labels=feature"
}],
"lastSaved": "2024-12-21T04:47:46.625Z",
"markdownDetails": "# heading\n**bold**\n[link](https://canny.io)",
"plaintextDetails": "heading\nbold\nlink",
"posts": [{
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"eta": "February 2024",
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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": "2024-12-21T04:47:46.625Z",
"reactions": {
"like": 2
},
"scheduledFor": null,
"status": "published",
"title": "Entry title",
"types": ["new", "improved"],
"url": "https://your-company.canny.io/changelog/entry-title"
}]
}
Comments
Users and admins can leave comments on posts. Therefore, comment objects are always associated with a post. The API allows you to fetch a specific comment, or a list of comments for a post.
The comment object
Attributes
id
string
A unique identifier for the comment.
author
User object
The user who created the comment.
board
Board object
The board the comment is associated with.
created
string
Time at which the comment was created, in ISO 8601 format.
imageURLs
array
An array of the URLs of the images associated with this comment.
internal
boolean
Whether or not the comment is an internal comment.
likeCount
number
The number of likes a comment has received.
mentions
array
An array of user objects who are mentioned in the comment.
parentID
string
The id of the comment that this comment is a reply to. If this comment is not a reply, this field will be null.
post
Post object
The post the comment is associated with.
private
boolean
If the comment is private from other users, only applies if the "Allow end-users to see each others' comments" setting is disabled.
reactions
object
The number of reactions a comment has received.
value
string
The text value of this comment.
Example comment object:
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"created": "2024-12-21T04:47:46.627Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2024-12-21T04:47:46.627Z",
"id": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2024-12-21T04:47:46.627Z",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"internal": false,
"likeCount": 2,
"mentions": [],
"parentID": "553c3ef8b8cdcd1501ba3333",
"post": {
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba2234",
"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"
}
Retrieve comment
Retrieves the details of an existing comment, specified by its id.
Arguments
apiKey
string
Your secret API key.
id
string
The comment's unique identifier.
Returns
Returns a comment object, if a valid id was supplied.
Endpoint
https://canny.io/api/v1/comments/retrieve
Method
POST
Example Request
$ curl https://canny.io/api/v1/comments/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=553c3ef8b8cdcd1501ba1238
Example Response
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"created": "2024-12-21T04:47:46.628Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2024-12-21T04:47:46.628Z",
"id": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2024-12-21T04:47:46.628Z",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"internal": false,
"likeCount": 2,
"mentions": [],
"parentID": "553c3ef8b8cdcd1501ba3333",
"post": {
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"eta": "February 2024",
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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 comments
Returns a list of comments. Include parameters to specify post, board, and pagination. Sorted by newest.
Arguments
apiKey
string
Your secret API key.
authorID
string (optional)
The id of the author you'd like to fetch comments for.
boardID
string (optional)
The id of the board you'd like to fetch comments for.
companyID
string (optional)
If specified, will only fetch posts created by users linked to the company with this custom identifier.
limit
number (optional)
The number of comments you'd like to fetch. Defaults to 10 if not specified.
postID
string (optional)
The id of the post you'd like to fetch comments for.
skip
number (optional)
The number of comments you'd like to skip before starting to fetch. Defaults to 0 if not specified.
Returns
A dictionary with a "comments" property that contains an array of comment objects. There's also a "hasMore" property that specifies whether this query returns more comments than the limit.
Endpoint
https://canny.io/api/v1/comments/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/comments/list -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=553c3ef8b8cdcd1501ba2468
Example Response
{
"comments": [{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"created": "2024-12-21T04:47:46.629Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2024-12-21T04:47:46.629Z",
"id": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2024-12-21T04:47:46.629Z",
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"internal": false,
"likeCount": 2,
"mentions": [],
"parentID": "553c3ef8b8cdcd1501ba3333",
"post": {
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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"
}],
"hasMore": false
}
Create comment
Creates a new 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).Arguments
apiKey
string
Your secret API key.
authorID
string
The unique identifier of the comment's author.
postID
string
The unique identifier of the comment's post.
value
string
The comment value. Optional if imageURLs are provided. Must be under 2500 characters.
imageURLs
array (optional)
An array of the URLs of comment's images.
internal
boolean (optional)
Whether this comment is only available for internal usage. Default is false. This can only be set to true if the author is a member of the company.
parentID
string (optional)
The unique identifier of the comment's parent, if this comment is a reply.
shouldNotifyVoters
boolean (optional)
Whether this comment should be allowed to trigger email notifications. Default is false.
Returns
Upon success, returns an object with a single key: id.
Endpoint
https://canny.io/api/v1/comments/create
Method
POST
Example Request
$ curl https://canny.io/api/v1/comments/create -X POST \
-d apiKey=YOUR_API_KEY \
-d authorID=553c3ef8b8cdcd1501ba1238 \
-d postID=553c3ef8b8cdcd1501ba1240 \
-d value="This is the comment's value"
Example Response
{
"id": "553c3ef8b8cdcd1501ba2200",
}
Delete comment
Deletes a comment.
Arguments
apiKey
string
Your secret API key.
commentID
string
The unique identifier of the comment.
Returns
Returns "success" if the comment was successfully deleted.
Endpoint
https://canny.io/api/v1/comments/delete
Method
POST
Example Request
$ curl https://canny.io/api/v1/comments/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d commentID=553c3ef8b8cdcd1501ba2200"
Example Response
success
Companies
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.
List companies
Returns a list of all companies associated with your company, ordered by created date.
Arguments
apiKey
string
Your secret API key.
search
string (optional)
A string to search by company name
segment
string (optional)
the URL name of the segment you want to use to filter companies
limit
number (optional)
The number of companies you'd like to fetch. Defaults to 10 if not specified.
skip
number (optional)
The number of companies you'd like to skip before starting to fetch. Defaults to 0 if not specified.
Returns
A dictionary with a "companies" property that contains an array of company objects. There's also a "hasMore" property that specifies whether this query returns more companies than the limit.
Endpoint
https://canny.io/api/v1/companies/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/companies/list -X POST \
-d apiKey=YOUR_API_KEY \
-d search=company
Example Response
{
"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"
}
],
"hasMore": false
}
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.
Arguments
apiKey
string
Your secret API key.
id
string
The identifier for your company.
created
date (optional)
The date the company was created in your system.
customFields
object (optional)
Any custom fields associated with the company. Each field name (key) must be between 0 and 30 characters long. If field values are strings, they must be less than 200 characters long.
monthlySpend
integer (optional)
The MRR for the company in dollars. This will be rounded to two decimal places.
name
string (optional)
The company's name. Must be between 0 and 100 characters long.
Returns
Upon success, returns an object with a single key: id.
Endpoint
https://canny.io/api/v1/companies/update
Method
POST
Example Request
$ curl https://canny.io/api/v1/companies/update -X POST -d '{
"apiKey": "YOUR_API_KEY",
"id": "company1",
"created": "2024-12-21T04:47:46.633Z",
"customFields": {
"number": "12",
"string": "value"
"boolean": true,
},
"monthlySpend": 500.59,
"name": "company 1"}' \
-H "Content-Type: application/json"
Example Response
{
"id": "company1"
}
Delete company
Deletes a company.
Arguments
apiKey
string
Your secret API key.
companyID
string
The identifier you used when creating the company.
Returns
Returns "success" if the company was successfully deleted.
Endpoint
https://canny.io/api/v1/companies/delete
Method
POST
Example Request
$ curl https://canny.io/api/v1/companies/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d companyID=company1"
Example Response
success
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
Attributes
id
string
A unique identifier for the opportunity.
closed
boolean
Whether the opportunity is closed.
name
string
The name of the opportunity.
postIDs
array
The list of post ids this opportunity is linked to.
salesforce
string
The unique identifier for the opportunity in Salesforce.
value
number
The value of the opportunity.
won
boolean
Whether the opportunity has been won.
Example opportunity object:
{
"id": "61a942ed07bfe27b60109ee0",
"closed": true,
"name": "Opportunity Name",
"postIDs": ["61a942ed07bfe27b60109eaf", "61a942ed07bfe27b60109ebc"],
"salesforceOpportunityID": "0063k00000zx6BkAAI",
"value": 1999.99,
"won": true
}
List opportunties
Returns a list of opportunities linked to posts in Canny.
Arguments
apiKey
string
Your secret API key.
limit
number (optional)
The number of opportunities you'd like to fetch. Defaults to 10 if not specified.
skip
number (optional)
The number of opportunities you'd like to skip before starting to fetch. Defaults to 0 if not specified.
Returns
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.
Endpoint
https://canny.io/api/v1/opportunities/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/opportunities/list -X POST \
-d apiKey=YOUR_API_KEY
Example Response
{
"hasMore": false,
"opportunities": [{
"id": "61a942ed07bfe27b60109ee0",
"closed": true,
"name": "Opportunity Name",
"postIDs": ["61a942ed07bfe27b60109eaf", "61a942ed07bfe27b60109ebc"],
"salesforceOpportunityID": "0063k00000zx6BkAAI",
"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
Attributes
id
string
A unique identifier for the post.
author
User object
The user who authored the post. If the author's account has been deleted, this field will be null.
board
Board object
The board this post is associated with.
by
User object
The user who created the post on behalf of the author.
category
Category object
The category this post is assigned to, if any.
commentCount
number
The number of non-deleted comments associated with this post.
created
string
Time at which the post was created, in ISO 8601 format.
clickup.linkedTasks
array
A list of Clickup tasks that are linked with this post
details
string
Any details the user included in the post. This is the longer text field (where the shorter one is "title").
eta
string
The month and year the post is estimated to be delivered.
imageURLs
array
An array of the URLs of the images associated with this post
jira.linkedIssues
array
A list of Jira issues that are linked with this post
owner
User
The owner of the post
roadmaps
array
The roadmaps the post is associated with
score
number
The number of votes that have been cast on this post.
status
string
The post's status: "open", "under review", "planned", "in progress", "complete", "closed", or any other status your team has set on the settings page.
statusChangedAt
string
Time at which the post's status was last changed
tags
array
The list of tag objects associated with this post.
title
string
A brief title describing the post. This is the shorter text input (where the longer is details).
url
string
The URL to the post's page.
Example post object:
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"created": "2017-07-15T22:11:00.000Z",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "524c3ef8b8cdcd1501ba246b",
"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": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba1238",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"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"
}]
},
"owner": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba2234",
"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.
Arguments
apiKey
string
Your secret API key.
boardID
string (optional)
The board that the post belongs to. Only required if fetching by urlName.
id
string (optional)
The post's unique identifier.
urlName
string (optional)
The post's unique urlName.
Returns
Returns a post object, if a valid id was supplied.
Endpoint
https://canny.io/api/v1/posts/retrieve
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=553c3ef8b8cdcd1501ba1238
Example Response
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"created": "2024-12-21T04:47:46.637Z",
"email": "test@test.test",
"isAdmin": true,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2024-12-21T04:47:46.637Z",
"id": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "524c3ef8b8cdcd1501ba246b",
"created": "2024-12-21T04:47:46.637Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba1238",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2024-12-21T04:47:46.637Z",
"customFields": [{
"id": "553c3ef8b8cdcd1501ba2238",
"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"
}]
},
"mergeHistory":[{
"created":"2024-12-21T04:47:46.637Z",
"post": {
"created":"2024-12-21T04:47:46.637Z",
"details":"Awesome feature post details",
"id": "553c3ef8b8cdcd1501ba6789",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"owner": {
"id": "553c3ef8b8cdcd1501ba123a",
"created": "2024-12-21T04:47:46.637Z",
"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": "2024-12-21T04:47:46.637Z",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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.
Arguments
apiKey
string
Your secret API key.
boardID
string (optional)
The id of the board you'd like to fetch posts for.
authorID
string (optional)
If specified, will only fetch posts by the author with this id.
companyID
string (optional)
If specified, will only fetch posts created by users linked to the company with this custom identifier.
tagIDs
array (optional)
If specified, will only fetch posts tagged with at least one of the tags in the array.
limit
number (optional)
The number of posts you'd like to fetch. Defaults to 10 if not specified.
search
string (optional)
If specified, will only fetch posts that match your search query.
skip
number (optional)
The number of posts you'd like to skip before starting to fetch. Defaults to 0 if not specified.
sort
string (optional)
The order in which the posts should be fetched. Options include: "newest", "oldest", "relevance", "score", "statusChanged", "trending". Defaults to "newest" if not specified. The "relevance" sort can only be specified if a search value has been specified.
status
string (optional)
A comma separated list of statuses. Only posts with these statuses will be fetched. Defaults to "open,under review,planned,in progress" if not specified.
Returns
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.
Endpoint
https://canny.io/api/v1/posts/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/list -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=553c3ef8b8cdcd1501ba1234
Example Response
{
"hasMore": true,
"posts": [{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"created": "2024-12-21T04:47:46.638Z",
"email": "test@test.test",
"isAdmin": false,
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
},
"board": {
"created": "2024-12-21T04:47:46.638Z",
"id": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "524c3ef8b8cdcd1501ba246b",
"created": "2024-12-21T04:47:46.638Z",
"email": "test@john.test",
"isAdmin": true,
"name": "John Doe",
"url": "https://your-company.canny.io/admin/users/john-doe",
"userID": "5678"
},
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba1238",
"status": "to do",
"url": "https://app.clickup.com/t/123456"
}]
},
"commentCount": 10,
"created": "2024-12-21T04:47:46.638Z",
"customFields": [{
"id": "553c3ef8b8cdcd1501ba2238",
"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"
}]
},
"mergeHistory":[{
"created":"2024-12-21T04:47:46.638Z",
"post": {
"created":"2024-12-21T04:47:46.638Z",
"details":"Awesome feature post details",
"id": "553c3ef8b8cdcd1501ba6789",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"owner": {
"id": "553c3ef8b8cdcd1501ba123a",
"created": "2024-12-21T04:47:46.638Z",
"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": "2024-12-21T04:47:46.638Z",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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).Arguments
apiKey
string
Your secret API key.
authorID
string
The unique identifier of the post's author.
boardID
string
The unique identifier of the post's board.
byID
string (optional)
The identifier of the admin who creates the post on behalf of the author. This will be visible in the post.
categoryID
string (optional)
The unique identifier of the post's category or subcategory.
customFields
object (optional)
Any custom fields associated with the post. Each field name (key) must be between 0 and 30 characters long. If field values are strings, they must be less than 200 characters long.
details
string
The post details.
eta
string (optional)
The estimated date of the post's completion. In the format of MM/YYYY, eg, 06/2022.
etaPublic
boolean (optional)
If the ETA should be made visible to all users.
title
string
The post title.
ownerID
string (optional)
The ID of the user responsible for the completion of the work described in the post.
imageURLs
array (optional)
An array of the URLs of post's images.
createdAt
string (optional)
If the post is being moved from another source, the date this post was originally created in ISO 8601 format.
Returns
Upon success, returns an object with a single key: id.
Endpoint
https://canny.io/api/v1/posts/create
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/create -X POST -d '{
"apiKey": "YOUR_API_KEY",
"authorID": "553c3ef8b8cdcd1501ba1238",
"boardID": "553c3ef8b8cdcd1501ba1234",
"customFields": {
"number": 12,
"string": "value"
},
"details": "This is the post's details",
"title": "Post Title"}' \
-H "Content-Type: application/json"
Example Response
{
"id": "553c3ef8b8cdcd1501ba1240",
}
Change post category
Changes a post's category specified by its id.
Arguments
apiKey
string
Your secret API key.
categoryID
string (optional)
The category's unique identifier. Setting it to "null" removes the category of the post.
postID
string
The post's unique identifier.
Returns
Returns the updated post if the post's category was successfully changed.
Endpoint
https://canny.io/api/v1/posts/change_category
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/change_category -X POST \
-d apiKey=YOUR_API_KEY \
-d categoryID=523c3ef8b8cdcd1501ba123a \
-d postID=553c3ef8b8cdcd1501ba1238
Example Responses
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "524c3ef8b8cdcd1501ba246b",
"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": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba1238",
"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"
}]
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "553c3ef8b8cdcd1501ba6789",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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.
Arguments
apiKey
string
Your secret API key.
changerID
string
The identifier of the admin to record as having changed the post's status. This will be visible in the post's activity section.
postID
string
The post's unique identifier.
shouldNotifyVoters
boolean
Whether or not to notify non-admin voters of the status change.
status
string
The status to change the post to. Options include: "open", "under review", "planned", "in progress", "complete", "closed", or any other status your team has set on the settings page.
commentValue
string
The comment attached to this status change. If the comment includes line breaks, use "
" instead of directly inputting the line breaks.
commentImageURLs
array
An array of the URLs of the images associated with this status change.
Returns
Returns the updated post if the post's status was successfully changed.
Note:
If you try to change a post's status to its current status (eg. "planned" to "planned"), the endpoint will still respond with the updated post but none of the side-effects will trigger (post activity unit, slack notification, user notification, etc).Endpoint
https://canny.io/api/v1/posts/change_status
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/change_status -X POST \
-d apiKey=YOUR_API_KEY \
-d changerID=553c3ef8b8cdcd1501ba123a \
-d postID=553c3ef8b8cdcd1501ba1238 \
-d shouldNotifyVoters=true \
-d status="in progress"
Example Responses
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "524c3ef8b8cdcd1501ba246b",
"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": "553c3ef8b8cdcd1501ba2234",
"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"
}]
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "553c3ef8b8cdcd1501ba6789",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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"}
Add post tag
Adds a tag to a post. Both post and tag are specified by their unique id.
Arguments
apiKey
string
Your secret API key.
postID
string
The post's unique identifier.
tagID
string
The tag's unique identifier.
Returns
Returns the updated post if the tag was successfully added.
Note:
If you try to add a tag that has already been added, the endpoint will still respond with the updated post, even though no tag has been added.Endpoint
https://canny.io/api/v1/posts/add_tag
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/add_tag -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=553c3ef8b8cdcd1501ba1238
-d tagID=553c3ef8b8cdcd1501ba12bb
Example Responses
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "524c3ef8b8cdcd1501ba246b",
"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": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba1238",
"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"
}]
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "553c3ef8b8cdcd1501ba6789",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba3234",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2018-04-20T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba12bb",
"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.
Arguments
apiKey
string
Your secret API key.
postID
string
The post's unique identifier.
tagID
string
The tag's unique identifier.
Returns
Returns the updated post if the tag was successfully remove.
Note:
If you try to remove a tag that isn't assigned to the post, the endpoint will still respond with the updated post, even though no tag has been removed.Endpoint
https://canny.io/api/v1/posts/remove_tag
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/remove_tag -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=553c3ef8b8cdcd1501ba1238
-d tagID=553c3ef8b8cdcd1501ba12bb
Example Responses
{
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": {
"id": "524c3ef8b8cdcd1501ba246b",
"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": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba1238",
"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"
}]
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "553c3ef8b8cdcd1501ba6789",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"created": "2017-08-30T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba3234",
"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.
Arguments
apiKey
string
Your secret API key.
postID
string
The unique identifier of the post.
customFields
object (optional)
Any custom fields associated with the post. Each field name (key) must be between 0 and 30 characters long. If field values are strings, they must be less than 200 characters long.
details
string (optional)
The post details.
eta
string (optional)
The estimated date of the post's completion. In the format of MM/YYYY, eg, 06/2022.
etaPublic
boolean (optional)
If the ETA should be made visible to all users.
title
string (optional)
The post title.
imageURLs
array (optional)
An array of the URLs of post's images.
Returns
Returns "success" if the post was updated successfully.
Endpoint
https://canny.io/api/v1/posts/update
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/update -X POST -d '{
"apiKey": "YOUR_API_KEY",
"postID": "553c3ef8b8cdcd1501ba1238",
"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"
Example Response
success
Delete post
Deletes an existing post.
Arguments
apiKey
string
Your secret API key.
postID
string
The unique identifier of the post.
Returns
Returns "success" if the post was deleted successfully.
Endpoint
https://canny.io/api/v1/posts/delete
Method
POST
Example Request
$ curl https://canny.io/api/v1/posts/delete -X POST -d '{
"apiKey": "YOUR_API_KEY",
"postID": "553c3ef8b8cdcd1501ba1238"' \
-H "Content-Type: application/json"
Example Response
success
Roadmaps
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
Attributes
id
string
A unique identifier for the roadmap.
archived
boolean
Whether the roadmap has been archived.
created
string
Time at which the roadmap was created, in ISO 8601 format.
name
string
The name of the roadmap.
postCount
number
The number of posts associated with the roadmap.
url
string
The URL to the roadmap in the admin view.
Example roadmap object:
{
"id": "553c3ef8b8cdcd1501ba12bb",
"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
Attributes
id
string
A unique identifier for the status change.
changeComment
Comment object
The comment attached to this status change. Only imageURLs and value fields are included.
changer
User object
The user who changed the status.
created
string
Time at which the status was changed, in ISO 8601 format.
post
Post object
The post that had its status changed.
status
string
The status the post was changed to.
Example status change object:
{
"changeComment": {
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"value": "This is the status change comment value"
},
"changer": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba12bb",
"post": {
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba1238",
"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"
}]
},
"mergeHistory":[{
"created":"2018-06-17T22:42:37.167Z",
"post": {
"created":"2018-06-17T22:42:00.797Z",
"details":"Awesome feature post details",
"id": "553c3ef8b8cdcd1501ba6789",
"imageURLs":[],
"title":"Another awesome feature request"
}
}],
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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.
Arguments
apiKey
string
Your secret API key.
boardID
string (optional)
The id of the board you'd like to fetch status changes for.
limit
number (optional)
The number of status changes you'd like to fetch. Defaults to 10 if not specified.
skip
number (optional)
The number of status changes you'd like to skip before starting to fetch. Defaults to 0 if not specified.
Returns
A dictionary with a "statusChanges" property that contains an array of status change objects. There's also a "hasMore" property that specifies whether this query returns more status changes than the limit.
Endpoint
https://canny.io/api/v1/status_changes/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/status_changes/list -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=553c3ef8b8cdcd1501ba1234
Example Response
{
"hasMore": false,
"statusChanges": [{
"changeComment": {
"imageURLs": [
"https://canny.io/images/93fc5808937760b82c3dc00aa5cd86b8.png",
"https://canny.io/images/316e5600645b81e4be287a52d506dbfd.jpg"
],
"value": "The status has changed!"
},
"changer": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba12bb",
"post": {
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"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"]
},
"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"
}]
},
"score": 72,
"status": "in progress",
"statusChangedAt": "2017-08-24T23:22:00.000Z",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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"
}]
}
The tag object
Attributes
id
string
A unique identifier for the tag.
board
Board object
The board this tag is associated with.
created
string
Time at which the tag was created, in ISO 8601 format.
name
string
The name of the tag.
postCount
number
The number of posts that have been assigned this tag.
url
string
The URL to the board, filtered to just posts that have been assigned this tag.
Example tag object:
{
"id": "553c3ef8b8cdcd1501ba12bb",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba4400",
"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.
Arguments
apiKey
string
Your secret API key.
id
string
The tag's unique identifier.
Returns
Returns a tag object, if a valid id was supplied.
Endpoint
https://canny.io/api/v1/tags/retrieve
Method
POST
Example Request
$ curl https://canny.io/api/v1/tags/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=553c3ef8b8cdcd1501ba12bb
Example Response
{
"id": "553c3ef8b8cdcd1501ba12bb",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba4400",
"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.
Arguments
apiKey
string
Your secret API key.
boardID
string
The unique identifier of the board the tag should be created for.
name
string
The name of the tag. Must be between 1 and 30 characters long.
Returns
Returns the tag object, if it was successfully created or already exists.
Endpoint
https://canny.io/api/v1/tags/create
Method
POST
Example Request
$ curl https://canny.io/api/v1/tags/create -X POST \
-d apiKey=YOUR_API_KEY \
-d boardID=553c3ef8b8cdcd1501ba4400 \
-d name="New Tag"
Example Response
{
"id": "553c3ef8b8cdcd1501ba12bb",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba4400",
"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
Attributes
id
string
A unique identifier for the user.
alias
string
Name used in place of the user's actual name in anonymized boards. This field can be null if user has not previously engaged with the company.
avatarURL
string
Link to the user's avatar image.
companies
array
A list of companies the user is associated with.
created
string
Time at which the user was created, in ISO 8601 format.
customFields
object
Any custom fields associated with the user.
email
string
The user's email. This field can be null, for example when you create a new user by voting on behalf of them.
isAdmin
boolean
Whether or not the user is a Canny admin.
lastActivity
string
Time at which the user interacted with your company for the last time, in ISO 8601 format.
name
string
The user's name.
url
string
The URL of the user's profile.
userID
string
The user's unique identifier in your application. This field can be null. We only have this data if the user was authenticated via single sign-on, or if it was added via API.
Example user object:
{
"id": "553c3ef8b8cdcd1501ba123a",
"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": "2024-12-21T04:47:46.650Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "test@test.test",
"isAdmin": false,
"lastActivity": "2024-12-21T04:47:46.650Z",
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
}
List users
Lists a company's users.
Arguments
apiKey
string
Your secret API key.
limit
number (optional)
The number of entries you'd like to fetch. Defaults to 10 if not specified. Maximum value allowed: 100.
skip
number (optional)
The number of entries you'd like to skip before starting to fetch. Defaults to 0 if not specified.
Returns
Returns a list of users.
Endpoint
https://canny.io/api/v1/users/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/users/list -X POST \
-d apiKey=YOUR_API_KEY \
-d limit=100
-d skip=100
Example Response
[{
"id": "553c3ef8b8cdcd1501ba123a",
"alias": "Green Fish",
"avatarURL": "https://canny.io/images/a3db0133d1e7d9122832b67b2c4caaaa.jpg",
"created": "2024-12-21T04:47:46.651Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "test@test.test",
"isAdmin": false,
"lastActivity": "2024-12-21T04:47:46.651Z",
"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.
Arguments
apiKey
string
Your secret API key.
email
string (optional)
The user's email.
id
string (optional)
The user's unique identifier from Canny.
userID
string (optional)
The user's unique identifier in your application.
Returns
Returns a user object, if a valid identifier was supplied.
Endpoint
https://canny.io/api/v1/users/retrieve
Method
POST
Example Request
$ curl https://canny.io/api/v1/users/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=553c3ef8b8cdcd1501ba123a
Example Request
$ curl https://canny.io/api/v1/users/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d userID=1234
Example Request
$ curl https://canny.io/api/v1/users/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d email="test@test.test"
Example Response
{
"id": "553c3ef8b8cdcd1501ba123a",
"alias": "Green Fish",
"avatarURL": "https://canny.io/images/a3db0133d1e7d9122832b67b2c4caaaa.jpg",
"created": "2024-12-21T04:47:46.652Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "test@test.test",
"isAdmin": false,
"lastActivity": "2024-12-21T04:47:46.652Z",
"name": "Sally Doe",
"url": "https://your-company.canny.io/admin/users/sally-doe",
"userID": "1234"
}
Create or update user
Finds the id for a 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.
Note:
the email, name and avatarURL properties of admin users cannot be modified through the Canny API. A Canny admin will need to login to Canny to update this information manually.Arguments
apiKey
string
Your secret API key.
alias
string (optional)
The user's alias
avatarURL
string (optional)
The URL pointing to the user's avatar image.
companies
array (optional)
A list of companies the user is associated with.
created
date (optional)
The date the user was created in your system.
customFields
object (optional)
Any custom fields associated with the user. Each field name (key) must be between 0 and 30 characters long. If field values are strings, they must be less than 200 characters long.
email
string (optional)
The user's email.
name
string
The user's name. Must be between 1 and 50 characters.
userID
string
The user's unique identifier in your application.
Returns
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.
Endpoint
https://canny.io/api/v1/users/create_or_update
https://canny.io/api/v1/users/find_or_create (deprecated)
Method
POST
Example Request
$ curl https://canny.io/api/v1/users/find_or_create -X POST -d '{
"apiKey": "YOUR_API_KEY",
"alias": "Green Fish",
"companies": [{
"created": "2024-12-21T04:47:46.653Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"id": "company123",
"monthlySpend": 500.00,
"name": "company name"
}],
"created": "2024-12-21T04:47:46.653Z",
"customFields": {
"field1": "value1",
"field2": "value2"
},
"email": "sally@netflix.com",
"name": "Sally Doe",
"userID": "1234-5678"}' \
-H "Content-Type: application/json"
Example Response
{
"id": "553c3ef8b8cdcd1501ba123a",
}
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.
Arguments
apiKey
string
Your secret API key.
id
string
The unique identifier of the user.
Returns
Returns "success" if the user was successfully deleted.
Endpoint
https://canny.io/api/v1/users/delete
Method
POST
Example Request
$ curl https://canny.io/api/v1/users/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d userID=553c3ef8b8cdcd1501ba2200"
Example Response
success
Remove 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.
Arguments
apiKey
string
Your secret API key.
companyID
string
The identifier of your company.
id
string
The 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.
Endpoint
https://canny.io/api/v1/users/remove_user_from_company
Method
POST
Example Request
$ curl https://canny.io/api/v1/users/remove_user_from_company -X POST -d '{
"apiKey": "YOUR_API_KEY",
"companyID": "company1",
"id": "553c3ef8b8cdcd1501ba123a"}' \
-H "Content-Type: application/json"
Example Response
"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
Attributes
id
string
A unique identifier for the vote.
board
Board object
The board this vote is associated with.
by
User object
The admin who cast this vote on behalf of a user. If the user voted themselves, this field will be null.
created
string
Time at which the vote was first cast, in ISO 8601 format.
post
Post object
The post this vote is associated with.
voter
User object
The user this post is associated with.
Example vote object:
{
"id": "553c3ef8b8cdcd1501ba123b",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba4400",
"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": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba2234",
"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": "553c3ef8b8cdcd1501ba123a",
"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",
}
}
Retrieve vote
Retrieves the details of an existing vote, specified by its id.
Arguments
apiKey
string
Your secret API key.
id
string
The vote's unique identifier.
Returns
Returns a vote object, if a valid id was supplied.
Endpoint
https://canny.io/api/v1/votes/retrieve
Method
POST
Example Request
$ curl https://canny.io/api/v1/votes/retrieve -X POST \
-d apiKey=YOUR_API_KEY \
-d id=553c3ef8b8cdcd1501ba123b
Example Response
{
"id": "553c3ef8b8cdcd1501ba123b",
"board": {
"created": "2017-08-30T13:32:01.000Z",
"id": "553c3ef8b8cdcd1501ba4400",
"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": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"eta": "February 2020",
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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": "553c3ef8b8cdcd1501ba123a",
"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.
Arguments
apiKey
string
Your secret API key.
boardID
string (optional)
The id of the board you'd like to fetch votes for.
companyID
string (optional)
If specified, will only fetch posts created by users linked to the company with this custom identifier.
limit
number (optional)
The number of votes you'd like to fetch. Defaults to 10 if not specified.
postID
string (optional)
Specify a postID to only fetch votes for a specific post.
skip
number (optional)
The number of votes you'd like to skip before starting to fetch. Defaults to 0 if not specified.
userID
string (optional)
Specify a userID to only fetch votes for a specific user.
Returns
A dictionary with a "votes" property that contains an array of vote objects. There's also a "hasMore" property that specifies whether this query returns more votes than the limit.
Endpoint
https://canny.io/api/v1/votes/list
Method
POST
Example Request
$ curl https://canny.io/api/v1/votes/list -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=553c3ef8b8cdcd1501ba2468
Example Response
{
"hasMore": false,
"votes": [{
"id": "553c3ef8b8cdcd1501ba123b",
"board": {
"created": "2017-07-10T11:22:00.000Z",
"id": "553c3ef8b8cdcd1501ba1234",
"name": "Feature Requests",
"postCount": 123,
"url": "https://your-company.canny.io/admin/board/feature-requests"
},
"by": null,
"created": "2017-07-15T22:11:00.000Z",
"post": {
"category": {
"id": "553c3ef8b8cdcd1501ba2234",
"name": "Dashboard",
"postCount": 42,
"url": "https://your-company.canny.io/admin/board/feature-requests?category=dashboard"
},
"commentCount": 2,
"id": "553c3ef8b8cdcd1501ba4444",
"imageURLs": [],
"jira": {
"linkedIssues": [{
"id": "123",
"key": "ID-123",
"url": "https://your-company.atlassian.net/browse/ID-123"
}]
},
"score": 13,
"status": "planned",
"tags": [{
"id": "553c3ef8b8cdcd1501ba3234",
"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": "553c3ef8b8cdcd1501ba123a",
"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"
},
"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",
}]
}
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).Arguments
apiKey
string
Your secret API key.
byID
string (optional)
The unique identifier of the user who cast the vote on behalf of the voter. Must be a Canny administrator.
postID
string
The unique identifier of the post to vote on.
voterID
string
The unique identifier of the voter.
Returns
Returns "success" if the vote was successfully created or already exists.
Endpoint
https://canny.io/api/v1/votes/create
Method
POST
Example Request
$ curl https://canny.io/api/v1/votes/create -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=553c3ef8b8cdcd1501ba1240 \
-d voterID=553c3ef8b8cdcd1501ba1238
Example Response
success
Delete vote
Deletes a vote.
Arguments
apiKey
string
Your secret API key.
postID
string
The unique identifier of the post to vote on.
voterID
string
The unique identifier of the voter.
Returns
Returns "success" if the vote was successfully deleted, or already doesn't exist.
Endpoint
https://canny.io/api/v1/votes/delete
Method
POST
Example Request
$ curl https://canny.io/api/v1/votes/delete -X POST \
-d apiKey=YOUR_API_KEY \
-d postID=553c3ef8b8cdcd1501ba1240 \
-d voterID=553c3ef8b8cdcd1501ba1238
Example Response
success
Webhooks
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.
You can set up webhooks for your account in
Your Subdomain > Settings > API
.The event object
Attributes
created
string
Time at which the event was created, in ISO 8601 format.
object
object
The object the event is about.
objectType
string
The type of object included in the event.
type
string
The type of event.
Example event object:
{
"created": "2017-07-15T22:11:00.000Z",
"object": {
"id": "553c3ef8b8cdcd1501ba1238",
"author": {
"id": "553c3ef8b8cdcd1501ba123a",
"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": "553c3ef8b8cdcd1501ba1234",
"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.
Event
post.created
Occurs when a new post is created.
post.deleted
Occurs when a post is deleted.
post.jira_issue_linked
Occurs when a Jira issue is linked to a post.
post.jira_issue_unlinked
Occurs when a Jira issue is unlinked from a post.
post.tag_added
Occurs when a post is tagged
post.tag_removed
Occurs when a post's tag is removed.
post.status_changed
Occurs when a post's status is changed.
comment.created
Occurs when a new comment is created.
comment.deleted
Occurs when a comment is deleted.
vote.created
Occurs when a user votes on a post.
vote.deleted
Occurs when a user unvotes on a post.
Webhook signatures
Canny signs all the webhooks it sends. Each request will include the following headers.
Headers
canny-timestamp
The number of milliseconds since the UNIX epoch. Use this field to avoid replayed requests.
canny-nonce
A random string, unique per request.
canny-signature
An HMAC (SHA-256) signature of the nonce, using your team's API key, encoded in Base64
You can verify a request originated from Canny by using your team's API key to verify the signature sent in the
canny-signature
header, by signing the nonce in canny-nonce
. The nonce is signed using SHA-256 and is Base64 encoded.Example verification function
Node.js
C#
Go
Java
PHP
Python
Ruby
import crypto from 'crypto';
function verify(request) {
const {
'canny-nonce': nonce,
'canny-signature': signature
} = request.headers;
const APIKey = 'YOUR_API_KEY';
const calculated = crypto
.createHmac('sha256', APIKey)
.update(nonce)
.digest('base64');
return signature === calculated;
}
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.
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.
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.
Arguments
apiKey
string
Your secret API key.
payload
object
The payload of the request detailing the author, sourceURL and source text. See below for more details.
payload.id
string
The unique identifier of the conversation or chat you are enqueuing.
payload.authorID
string
The author's unique identifier in your application. If the user does not exist, you can create them with the "Create or Update User" endpoint first.
payload.text
string
The text you want to extract features from e.g. a call transcript.
payload.sourceURL
string (optional)
An optional URL linking to the conversation or chat you are enqueuing.
payload.sourceType
string (optional)
An optional indicator of the source e.g. X (Twitter), Zoom, Instagram, ...
type
string
The type of content being enqueued. Currently only supports "call" and "conversation". Choose "call" if the transcript is from a call and "conversation" if it is from a chat conversation.
Returns
Returns "success" if the payload was enqueued. Otherwise an error describing the issue with your request.
Endpoint
https://canny.io/api/v1/ai/enqueue
Method
POST
Example Request
$ curl https://canny.io/api/v1/ai/enqueue -X POST -d '{
"apiKey": "YOUR_API_KEY",
"payload": {
"id": "conversationID",
"authorID": "5bc799625ca6bf6caff284dd",
"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"
Example Response
"success"