Productive API
API endpoint is https://api.productive.io/api/v2/
This API is implemented according to JSON API spec.
Authorization
To authorize yourself, add your API token to the X-Auth-Token header for every request.
API token can be generated using Productive application, navigating to Settings -> API integrations -> Generate new token
To access your organization data, add your organization ID to the X-Organization-Id header for every request.
Most resources have authorization on them. If successfully authorized, you will get a response containing the resource. However, if you aren’t authorized then you will be given HTTP status of 403, and an error message.
Content Negotiation
Content-Type
header must be set to application/vnd.api+json
.
While sending bulk requests, make sure to set Content-Type
to application/vnd.api+json; ext=bulk
.
When Content-Type
is not set as described, API will return 415 response status error.
Filtering
If you would like to add filtration to your query, you can do that by setting the supported filter parameters in the following way: ?filter[person_id]=24
.
In case you set filter parameter that is not supported for the query, you will get 400 status error:
{
"errors": [
{
"status": 400,
"title": "Unsupported Filter",
"detail": "Filter 'undefined' is not supported on this endpoint"
}
]
}
Filter Operations
There is also support for different filter operations. Allowed operations are:
-
eq
-
not_eq
-
contains
-
not_contain
-
gt
-
gt_eq
-
lt
-
lt_eq
To use operations for filtering, define it after the param name: ?filter[person_id][not_eq]=24
.
NOTE: Not all endpoints support filter operations. If an endpoint supports filter operations, it will be listed in the documentation for that endpoint.
Logical operation groups
Endpoints support logical operations as well. The structure for the logical operations are as follows:
# logical *operation*
filter[$op]=or|and
# each *operation* can have one or more *operands* denoted by index numbers
filter[{index}][{operand}]
# *operand* can be a direct value
# Example:
filter[$op]=or
filter[0][name][eq]=Productive
filter[1][date][gt]=2024-01-01
filter[2][date][eq]=2023-01-01
# or be another logical operation
# Example:
filter[$op]=or
filter[0][name][eq]=Productive
filter[1][$op]=and
filter[1][0][date][gt]=2024-01-01
filter[1][1][date][eq]=2023-01-01
DateTime filtering
By default all values sent to date or datetime filters are parsed as dates
(only their date component is used to do the filtering)
You can get your filter value parsed as datetime by using the filteringSkipDatetimeCastToDate
flag.
To enable this feature, append the filteringSkipDatetimeCastToDate
flag to your request header (X-Feature-Flags
).
This functionality applies only to DateTime
fields (e.g., created_at
, updated_at
).
In case it is used on a Date
field (eg., end_date
or start_date
) flag will be ignored and values evaluate as Dates
.
The table below illustrates how the filter value is interpreted based on whether the filteringSkipDatetimeCastToDate
flag is enabled or disabled
filteringSkipDatetimeCastToDate Flag | Value | Parsed as |
---|---|---|
Disabled | 2024-09-12 | Date |
Disabled | 2024-09-12T10:15:30.000+02.00 | Date |
Enabled | 2024-09-12 | Date |
Enabled | 2024-09-12T10:15:30.000+02.00 | DateTime |
Granulation of a filter with datetime value is one second.
NOTE: Filter values are included in the URL and must be properly URL-encoded. For instance, the character +
should be encoded as %2B
and -
as %2D
Sorting
To sort query results, you can use sort parameter, passing available sort params for the resource: ?sort=name
.
All available sort params are defined separately for each resource. You can provide desired sort order using -
sign (?sort=-name
), where no -
defines ascending and -
defines descending order by the given sort parameter.
If a given parameter is not supported, Unsupported Sort
error (with status 400) will be raised:
{
"errors": [
{
"status": 400,
"title": "Unsupported Sort",
"detail": "Sort by 'unsupported' is not supported on this endpoint"
}
]
}
Pagination
Pagination has to be set in the following style:
?page[number]=2&page[size]=20
Where page[number]=
is the page you want to view, and page[size]=
is the number of resources you want to return.
To check pagination settings or how many resources there are in total, check the
meta
section in the response of your request.
There you can see the following:
current_page
- 1 by default or the value you put in page[number]
total_pages
- total_count
/page_size
rounded up
total_count
- total number of resources you have
page_size
- 30 by default or the value you put in page[size]
max_page_size
- 200
An example of how to use pagination:
Sending page[number]=2
and page[size]=15
will result in seeing resources from 16 to 30 on page 2,
and the total_pages number will be total_count
/15 rounded up.
API changes
Changelog is located at https://developer.productive.io/CHANGELOG.md
You can also subscribe to our email list for API change announcements. If you use API integrations, it is recommended to subscribe and stay on track with updates.
You can later unsubscribe from this email list. We will occasionally send emails related to changes in our APIs to subscribers.
Rate Limits
The API utilizes rate limiting to control the number of requests that can be made within a specified time period. This ensures fair usage of resources and prevents abuse or overloading of the server.
The rate limits are structured around a 100 requests per 10 seconds
with additional limit of 4000 requests per 30 minutes
allowing for occasional bursts of higher request rates in short intervals. If the rate limit is exceeded, the server will respond with an appropriate HTTP status code (e.g., 429 Too Many Requests
), indicating that the client should slow down and comply with the rate limits.
Special consideration is given to the reports endpoint due to its resource-intensive nature. To manage its usage effectively, additional throttling measures are implemented, allowing a maximum of 10 requests within a 30-second
timeframe.
Generated by aglio on 24 Mar 2025