This feature is currently in beta and we’ve been actively porting our frontend to use our API over CORS. Our long-term vision is that our frontend and our customers’ API applications use identical endpoints.

The new Activity API has three endpoints.

  • /api/activities/search.json - Includes activity entries across all products.
  • /api/products/{product_id}/activities.json - Includes activity entries for a single product.
  • /api/products/{product_id}/items/{item_number}/activities.json - Includes activity entries for a single item.

All endpoints accept the the following arguments:

  • q – The query you’d like ran (e.g. “dashboard bug”). This item is optional. Querying with an empty query string will return all items for all products the requesting user is a member of.
  • sort – Which field to order results by. By default, we return the best match according to the search index.
  • order – Which order to sort the results in (asc or desc).
  • offset – Which record in the result set to start at. Defaults to 0.
  • limit – How many records to return starting from offset. Defaults to 250.

The search query syntax supports a number of fields for filtering. These fields work by showing activity entries that belong to items that match these filters. The following fields can be appended to your query specified in q to either filter results for keywords in q (e.g. design -tag:mobile) or as values in the facets argument:

All of the above facets allow for negative querying. To apply a negative facet simply add - to the front of the facet name (e.g. -tag:foo would return activity for items that are not tagged with “foo”). This is particularly interesting when you consider the has and is facets. For instance -has:pr would return any activity for an item that does not have a PR issued against it. You can, of course, do -keyword or -title:"some phrase".

The API is JSON only and returns the following arguments:

  • q – The query as parsed by the backend. I would give our query parser a solid B- right now; there’s for sure some edge cases that may not work. Please let us know on Twitter if you have a query mis-match. We’re logging them in Kibana as well to keep an eye on any issues.
  • total_count – The total number of items that matched the given query.
  • activities – A list of activity objects.

It’s important to note a few things about the way search works:

  • Keywords and search phrases are special. Unlike other facets, they are grouped with an AND as opposed to an OR. In other words foo "my stuff" matches foo AND "my stuff" while assignee:1 assignee:2 matches assignee:1 OR assignee:1.
  • The + modifier is implied. No need to do +tag:foo +tag:bar.
  • It is possible to create nonsensical search queries, such as is:child has:children, which would never return results because our data model doesn’t allow sub-items to have sub-items. Use your newfound powers responsibly.
  • The API returns total_count and allows offset and limit. This should make pagination reasonably easy to implement.
Did this answer your question?