Discussions

Discussion Listing

> curl -H "Accept: application/vnd.tender-v1+json" "https://USER:PASS@api.tenderapp.com/YOURSITE/discussions"
{
  "offset": 0,
  "total": 329,
  "per_page": 30,
  "discussions": [
    {DISCUSSION}, {DISCUSSION}, etc
  ]
}

Sort

The default sort is by last_updated_at, which is the date of the last customer reply. You can also use ?sort=created to sort by creation date, or ?sort=updated to sort by updated_at instead.

Public

You can filter discussions to only get public ones with public=1.

Since

You can request only a range of discussions:

  • ?since=12345: only discussions with id >12345
  • ?since=2013-06-01: if you're sorting by updated_at, this will be all discussions updated since that date, and if you are using the default sort (last_updated_at), this will be all discussions with a customer reply since that date. Sort must be in the form YYYY-MM-DD.

Discussions by state:

> curl -H "Accept: application/vnd.tender-v1+json" "https://USER:PASS@api.tenderapp.com/YOURSITE/discussions/pending"
{
  "offset": 0,
  "total": 329,
  "per_page": 30,
  "discussions": [
    {DISCUSSION}, {DISCUSSION}, etc
  ]
}

Discussion For User

Find discussions created by a specific user who has a registered account on Tender.

user_id - id of the registered user user_email - email of the registered user (user user_id OR user_email)

> curl -H "Accept: application/vnd.tender-v1+json" "https://USER:PASS@api.tenderapp.com/YOURSITE/discussions?user_id=1234"
{
  "offset": 0,
  "total": 329,
  "per_page": 30,
  "discussions": [
    {DISCUSSION}, {DISCUSSION}, etc
  ]
}

Discussion For Current User

Find discussions created by the current (logged in) user

user_current=1

> curl -H "Accept: application/vnd.tender-v1+json" "https://USER:PASS@api.tenderapp.com/YOURSITE/discussions?user_current=1"
{
    "offset": 0,
    "total": 329,
    "per_page": 30,
    "discussions": [
    {DISCUSSION}, {DISCUSSION}, etc
    ]
}

Discussion For Anonymous User

Find discussions created by a user who hasn't registered for a Tender account, but used their email when submitting a new discussion.

user_email - Email to filter on

> curl -H "Accept: application/vnd.tender-v1+json" "https://USER:PASS@api.tenderapp.com/YOURSITE/discussions?user_email=some-email@gmail.com"
{
    "offset": 0,
    "total": 329,
    "per_page": 30,
    "discussions": [
    {DISCUSSION}, {DISCUSSION}, etc
    ]
}

The discussions_href is typically fairly complicated URL template. You can view all discussions for a site, or just in a user, queue, or category. For example, here is the category discussions_href value:

https://api.tenderapp.com/help/categories/12345/discussions{-opt|/|state}{state}{-opt|?|page,user_email,since}{-join|&|page,user_email,since}

  • Expanded to show all discussions for this category: https://api.tenderapp.com/help/categories/12345/discussions
  • Expanded to show all pending discussions: https://api.tenderapp.com/help/categories/12345/discussions/pending. Valid states are:
    • new - "Open" discussions that have never been responded to by a support user.
    • open - Non-resolved discussion with no assigned tickets.
    • assigned - Non-resolved discussion with at least one assigned ticket.
    • resolved - Resolved discussions.
    • pending - Discussions where the last comment is made by a non-supporter. This is the same as the inbox queue in the dashboard.
    • deleted - Deleted/spam discussions.
  • Expanded to show page 2 of the discussions: https://api.tenderapp.com/yoursite/categories/12345/discussions?page=2
  • Expanded to show page 2 of the assigned discussions: https://api.tenderapp.com/yoursite/categories/12345/discussions/assigned?page=2
  • Expanded to show only records created since ID 1223345: https://api.tenderapp.com/yoursite/categories/12345/discussions?since=1223345

Single Discussion

You can find a single discussion either by its id, or with the category-permalink/number.

> curl -H "Accept: application/vnd.tender-v1+json" "https://USER:PASS@api.tenderapp.com/YOURSITE/categories/problems/discussions/123"

equivalent to

> curl -H "Accept: application/vnd.tender-v1+json" "https://USER:PASS@api.tenderapp.com/YOURSITE/discussions/12345"
{
  "title": "Ave response time metrics",
  "permalink": "ave-response-time-metrics",
  "number": 123,
  "author_email": "customer@company.com",
  "author_name": "Customer",
  "public": true,
  "via": "web",
  "unread": false,
  "category_id": 10000,
  "redirection_id": null,
  "private_body": null,
  "comments_count": 2,
  "avg_response_time": 31476,
  "state": "resolved",
  "watched_discussion_count": 2,
  "hidden": false,
  "user_id": 12345,
  "last_user_id": 12345,
  "last_comment_id": 12345,
  "last_via": "web",
  "last_author_email": "supporter@company.com",
  "last_author_name": "Support User",
  "created_at": "2009-07-28T12:26:55Z",
  "updated_at": "2009-07-28T12:26:55Z",
  "last_updated_at": "2009-07-28T21:11:31Z",
  "html_href": "https://help.tenderapp.com/discussions/problems/1259",
  "href": "https://api.tenderapp.com/YOURSITE/discussions/12345",
  "comments_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/comments",
  "queue_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/queue?queue={queue_id}",
  "unqueue_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/unqueue?queue={queue_id}",
  "toggle_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/toggle",
  "resolve_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/resolve",
  "unresolve_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/unresolve",
  "change_category_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/change_category?to={category_id}",
  "restore_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/restore",
  "acknowledge_href": "https://api.tenderapp.com/YOURSITE/discussions/12345/acknowledge",
  "comments": [
    {
      "author_name": "Customer",
      "author_email": "customer@company.com",
      "body": "Hello",
      "resolution": false,
      "number": 1,
      "via": "web",
      "user_is_supporter": false,
      "user_ip": "127.0.0.1",
      "user_agent": "Safari...",
      "referrer": "http://whatever",
      "skip_spam": true,
      "user_id": 54321,
      "formatted_body": "<div><p>Hello</p></div>",
      "html_href": "https://help.tenderapp.com/discussions/problems/1259",
      "user_href": "https://api.tenderapp.com/YOURSITE/users/15117",
      "created_at": "2009-07-28T12:26:55Z"
    },
    {COMMENT}, etc
  ]
}
  • To show page 2 of the comments: https://api.tenderapp.com/yoursite/discussions/12345?page=2

Discussion Attributes

  • title - the title of the discussion.
  • permalink - The part of the title used in discussion URLs. This is auto-generated from the title if not specified.
  • number (readonly) - unique number for this discussion in the current category.
  • public - boolean for specifying whether this discussion is public or private.
  • author_name - Shows the discussion author name, regardless if the discussion was posted by a regular or anonymous user.
  • author_email - Shows the discussion author email, regardless if the discussion was posted by a regular or anonymous user.
  • watched_discussion_count - Number of watchers for this discussion.
  • comments - This array of the actual comments is only shown when viewing a single discussion. Discussion lists will omit the comments completely. A limited amount of comments is returned. You can get more comments by calling the same URL with ?page=N
  • href - The API URL for this discussion.
  • html_href - The web URL for this discussion.

Comment Attributes

  • author_name - Shows the comment author name, regardless if the comment was posted by a regular or anonymous user.
  • author_email - Shows the comment author email, regardless if the comment was posted by a regular or anonymous user.
  • body - The original comment body.
  • skip_spam (supporter only) - skips spam checking.
  • user_ip - The IP of the author posting the comment. This is very useful for spam checking.
  • user_agent - The user agent of the author posting the comment. This is typically either the browser or the name of the HTTP client library that is accessing the API. This is very useful for spam checking.
  • referrer - The HTTP referrer of the author posting the comment. This is very useful for spam checking.
  • formatted_body (readonly) - The comment body after going through the Tender HTML formatter.
  • number (readonly) - The unique number of this comment in the current discussion.
  • resolution (readonly) - boolean specifying whether this comment was posted as a resolution to the discussion.
  • user_is_supporter (readonly) boolean specifying that the user was a supporter at the time the comment was posted.

Discussion Resources

  • comments_href - You can query this for the comments list. The first page of comments is returned. You can call the same URL with ?page=N to get the next pages.
  • category_href - This is the category that the discussion is a part of.
  • user_href - This is the user that posted the specified discussion/comment.

Spam Checking

If your Tender site has spam checking enabled, all API requests will be checked through the 3rd-party antispam service. It is recommended that you pass the user_ip, user_agent, and referrer fields if possible. For instance, if you are posting to the API from a web contact form, you should use the user's IP, user agent, and referrer from their contact form request.

Supporters can also pass a skip_spam attribute to skip spam checking for just that one comment.

Creating a Discussion

You can POST to the discussions action to create a new discussion. If you are a user / have the user's authentication, the discussion is always posted as that user. Support users can also send author_email and author_name to open a discussion on behalf of that user (this is probably the most common use case).

When creating a discussion as a support user on behalf of a user, you can also hook into the SSO/multipass system. Send the unique_id of the user to create the discussion for them; if the user does not exist in our system yet, their user record will be created, so be sure to also send the author_email, author_name, and trusted (not-a-spammer) attributes. You will get back a 422 if the user record is not valid.

Note: PHP's libcurl has a bug posting to a rails site where you cannot send multiple parameters with the same name, like attachments[] so if you need this, you may need to use a library like guzzle instead of libcurl.

You can specify extra information for the discussion by including an extras key in the discussion payload.

> curl -H "Accept: application/vnd.tender-v1+json" \
  -H "Content-Type: application/json" \
  -d '{"title":"MY TITLE", "public":true, "author_email":"USER@EXAMPLE","body":"MY BODY","skip_spam":true, "extras":{"favorite_food": "tacos"}}'
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/categories/:category_id/discussions"

Remember to set content-type!

Creating a Discussion with attachments

It is not possible at this time to create a discussion with attachments using JSON. It is however possible to create a discussion with attachments using a multipart/form-data POST, simulating a form post from a browser. You would use the same fields, and 0/1 for booleans. Here is a simple example:

curl -X POST \
  -H "X-Tender-Auth: TOKEN" \
  -H "Accept: application/vnd.tender-v1+json" \
  -F "title=TITLE" \
  -F "body=BODY" \
  -F "extras={\"user_status\": \"premium\"}" \
  -F "uploaded_assets[]=@file.png" \
  https://api.tenderapp.com/SITE/categories/XXX/discussions

Please note that depending on the library you are using, this may require some tweaking. When using a multipart form post, some libraries will attach a Content-Type to each part, like this:

--gezkkpwVSsaq-ZBGh0Quo9jT32b2PljaeLrr
Content-Disposition: form-data; name="title"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

Title
--gezkkpwVSsaq-ZBGh0Quo9jT32b2PljaeLrr
Content-Disposition: form-data; name="body"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

Body
--gezkkpwVSsaq-ZBGh0Quo9jT32b2PljaeLrr

Browsers do not do that, and the curl command given as an example doesn't do this either. Attaching a Content-Type to each text field will NOT work. Some libraries, such as the Apache HttpComponents offer a flag to change this behavior:

--SUwp6MNBn6C4xK9VXBcrq6LXYKaDzrP1-q
Content-Disposition: form-data; name="title"

Title
--SUwp6MNBn6C4xK9VXBcrq6LXYKaDzrP1-q
Content-Disposition: form-data; name="body"

Body
--SUwp6MNBn6C4xK9VXBcrq6LXYKaDzrP1-q

In doubt, you can use a tool like requestBin to look at your HTTP requests.

Replying to a Discussion

The same authentication rules apply for replies. The only difference between this and discussion creations is you do not specify the title or public attribute. (Remember to set the Content-Type header!)

See the comments API for more information.

> curl -H "Accept: application/vnd.tender-v1+json" \
  -H "Content-Type: application/json" \
  -d '{"author_email":"USER@EXAMPLE","body":"MY BODY","skip_spam":true}'
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/comments"

Discussion Actions

Discussions have various actions that can be performed on them. Some of them require support access, or the user to be the author that created the discussion. All of these URIs templates are provided with the discussion resource.

Toggle a discussion's private/public status

# POST /{site}/discussions/{discussion_id}/toggle
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/toggle"

Resolve a discussion

# POST /{site}/discussions/{discussion_id}/resolve
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/resolve"

Unresolve (re-open) a discussion

# POST /{site}/discussions/{discussion_id}/unresolve
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/unresolve"

Add Discussion to a Queue (Support only)

(This is a temporary URL and will likely change in the near future)

# POST /{site}/discussions/{discussion_id}/queue?queue={queue_id}
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/queue?queue=123"

Remove Discussion to a Queue (Support only)

(This is a temporary URL and will likely change in the near future)

# POST /{site}/discussions/{discussion_id}/unqueue?queue={queue_id}
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/unqueue?queue=123"

Acknowledge a Discussion (Move the discussion out of the pending inbox, support only).

# POST /{site}/discussions/{discussion_id}/acknowledge
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/acknowledge"

Unacknowledge a Discussion (Move the discussion to the pending inbox, support only).

# POST /{site}/discussions/{discussion_id}/unacknowledge
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/unacknowledge"

Restore a previously deleted or spammed Discussion

# POST /{site}/discussions/{discussion_id}/restore
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/restore"

Change a Discussion's category

# POST /{site}/discussions/{discussion_id}/change_category?to={category_id}
> curl -H "Accept: application/vnd.tender-v1+json" -d "" \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345/change_category?to=12345"

Delete a Discussion

# DELETE /{site}/discussions/{discussion_id}
> curl -H "Accept: application/vnd.tender-v1+json" -X DELETE \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345"

Mark Discussion as Spam

# DELETE /{site}/discussions/{discussion_id}?type=spam
> curl -H "Accept: application/vnd.tender-v1+json" -X DELETE \
  "https://EMAIL:PASS@api.tenderapp.com/YOURSITE/discussions/12345?type=spam"