Freedcamp Public API

Table of Contents

    Description

    This wiki describes Freedcamp public API things. Please email help@freedcamp.com to get early access.

    API end point: https://freedcamp.com/api/v1/.
    Postman collection which contains ready-to-go requests.
    Usage example (PHP).

    Setup

    Once our support enabled API beta for you please:

    1 - go to My Account/API

    2 - generate new API key

    3 - to access this page

    Authentification

    You may generate API keys on the API tab on My Account page. There are two types of keys: secured by API secret and not secured (you may change the type when you want). We highly recommend to use Secured keys for your needs when possible, but for quick testing, you may want to omit additional security.

    Not secured API keys

    Just pass the api_key with the key value as a GET or POST parameter, for example:

    https:// freedcamp.com/api/v1/sessions/current?api_key=api_key

    Not secured API keys have expiration time in one week. This may be changed later.

    Note that anyone who has access to your active not secured API key can do most of the actions available via API. NEVER share unsecured API key with anyone. If you suspect a key leak, please convert the key to the secured with API secret or delete it. We'll forbid some types of actions (like project or account deletion) for not secured keys soon.

    Zapier API keys

    These keys are used for Zapier integration. These keys will only work for Zapier requests. Note that anyone who has access to your Zapier API key is also able to connect to your Freedcamp data with Zapier. These keys also have restricted permissions.

    Secured API keys

    To auth with these keys, except the key itself you need to also pass a timestamp and hash parameters. A timestamp is the request timestamp (check you have properly set time on your server), and a hash is calculated using API secret in this way (PHP code for example):

    $hash = hash_hmac('sha1', $api_key . $timestamp, $api_secret);

    So the request will look like:

    https:// freedcamp.com/api/v1/sessions/current?api_key=api_key&timestamp=current_ts&hash=your_hash

    Get your API secret on the API tab on My Account page (you will need to enter your password). NEVER share API secret with anyone and do not pass it publicly. Let us know if you suspect API secret key leak.

    Passing API key in the header

    To not pass the API key as an URL parameter or inside POST body you may pass it via X-API-KEY header. This approach is used in requests in Postman collection.

    Other methods

    We plan to implement Oauth2 auth later on.

    Examples

    Postman collection which contains ready-to-go requests. Check "Setting up Postman" section below for details.
    Usage example (PHP).

    Request

    If a request should be done with any non-GET parameters (except auth parameters), it's supposed that they are passed as a form-data parameter with name 'data' and JSON-encoded value.

    Example:

    data: {"email": "test@email.com", "password": "11111111"}
    

    You may pass your auth credentials as POST data as well as in the GET with payload:

    api_key: api_key
    timestamp: current_ts
    hash: your_hash
    data: {"email": "test@email.com", "password": "11111111"}

    PUT requests

    All "update" requests which are described as PUT below should use POST requests. "Update" requests differ from "add" requests by passing id of the modified item. Later we may support PUT requests for updates.

    Response

    Each response returns JSON-encoded JS object with the following fields:

    name description
    http_code duplicates HTTP code passed in headers.
    msg OK' on successful request, an error description otherwise.
    error_id in the case when an error occurred and was logged by API, will contain corresponding error_id you can use to refer to in your support request to Freedcamp.
    maintenance (may be absent) in the case when there is active or upcoming Freedcamp maintenance scheduled (see Maintenance below).
    data specific for the request data, empty if an error happened or nothing to return. If there were some errors to show to a user, they will be placed under "errors" field. errors.general means some general error, errors._some_filed_name_ - means that error is for some posted field (like validation error).

    Examples of unsuccessful requests responses:

    {
      "http_code": 500,
      "msg": "Server error occured.",
      "error_id": 1621951,
      "data": [errors: {"general": "Server error occured, please try onу more time."}]
    }
    
    {
      "http_code": 401,
      "msg": "Wrong credentials",
      "error_id": 0,
      "data": []
    }
    
    {
      "http_code": 404,
      "msg": "Unknown method",
      "error_id": 0,
      "data": []
    }

    Maintenance

    When API endpoint is in the maintenance mode or there is an upcoming maintenance, API, in addition to standard fields (msg, data, etc.), returns maintenance field on each request, which has the next fields:

    name description
    start_ts a timestamp of maintenance start
    duration planned duration of the maintenance in minutes. A client should use it to inform users about planned time for service recovery ( which can be calculated as [start_ts + duration * 60]). Actual duration may be less than this value. Duration value may increase during the maintenance but has a low probability.
    msg a string with additional info for users about maintenance reasons. It can be empty. If it is not empty, should be shown somehow to the users in the client message about maintenance
    start_ts a timestamp of maintenance start
    duration planned duration of the maintenance in minutes. A client should use it to inform users about planned time for service recovery ( which can be calculated as [start_ts + duration * 60]). Actual duration may be less than this value. Duration value may increase during the maintenance but has a low probability.
    msg a string with additional info for users about maintenance reasons. It can be empty. If it is not empty, should be shown somehow to the users in the client message about maintenance.

    Example:

      "maintenance": {
        "start_ts": 1479848400,
        "duration": 60,
        "msg": ""
      }

    Usually, maintenance field is being sent 60 minutes before the maintenance.

    If Freedcamp AOI endpoint is already in the maintenance mode, it returns HTTP 503 in headers (and still returns the maintenance field):

    {
      "http_code": 503,
      "msg": "Maintenance is in progress",
      "error_id": 0,
      "maintenance": {
        "start_ts": 1479848400,
        "duration": 60,
        "msg": ""
      },
      "data": {}
    }

    No actions were executed if API endpoint returned 503.

    A client should not send requests more often than one per minute while getting 503 in response.

    It's possible that web-interface is in maintenance mode and API endpoint is not and vice versa.

    Supported methods

    /sessions

    Used to start a new session, get information of a current session or close a current session.
    Sessions are identified by a session token. Each device has own token with TTL of 1 week after the last action done in this session.
    If you have no active token when setting up the session, a new token will be created and returned, otherwise, the old one will be returned.

    GET

    Only /sessions/current will work.
    Returns the same data as POST request returns except for a token.

    POST

    WARNING: Is not supported now

    Returns session token and all info needed for the initial screen if valid email/password are passed. X-API-TOKEN should be empty. HTTP code 401 will be returned if a user can't be logged in using given credentials.

    Input data: email, password, oauth_provider, oauth_uid

    name description
    email should be always present except when signing in via Twitter which does not provide us with user's email
    password user password, may be empty when using OAuth token to sign in
    oauth_provider for signing in by OAuth provider,  should contain provider unique name. Allowed names are "facebook", "linkedin", "google", "twitter". Maybe empty or absent if signing in by email+password.
    oauth_uid OAuth provider unique id for a user. Maybe empty or absent if signing in by email+password
    mobile_app_version a version of the mobile app.

    Output (inside 'data'):

    name description
    token a session token to use further for API request inside headers
    user_id: user id of session user
    projects a list of all project groups which user has access to. Note that projects are ordered inside each group. To recreate projects order in projects dropdown in Web UI you should refer to groups list and projects list inside them.  

    Example of structure:

    "projects": [
          {
            "project_id": "914936",
            "role_name": "User",
            "role_type": "0",
            "project_name": "sdcscsdcscsdc",
            "project_description": "sdcsdcsdcsdcsdc",
            "project_color": "A86D54",
            "f_active": true,
            "f_can_delete": false,
            "f_can_manage": false,
            "f_can_leave": true,
            "notifications_count": 0,
            "users": [
              132942,
              309953,
              340312,
              377037,
              377039,
              377040
            ],
            "applications": [
                      6
                ]
            },
          "groups": [....],
          ...
       ]

    users: contains info about all users which current user can see in the projects he has access to. See structure example under /users request description.

    applications: (currently disabled) list of all FC applications. Structure example:
    "applications": [
          {
            "app_id": "1",
            "name": "Wall"
          },
          "2": {
            "app_id": "2",
            "name": "To-Do's"
          },
          ...
       ]

    groups: list of all available project groups, with the structure as for /groups:GET. You should use this list when you want to recreate the projects order of projects dropdown in Web UI.

    DELETE

    WARNING: Is not supported now

    Only /sessions/current will work.

    Closes current session, and invalidates current session token (so all devices have to set up a new session again).

    /groups

    GET

    Output:  

    groups: array with available groups Structure example:

        groups": [
          {
            "group_id": "267229",
            "name": "groupNamenew",
            "description": "some descr",
            "projects": [
              "415078",
              "415079",
            ],
            "applications": [],
            "f_managed": true
          },
          {
            "group_id": "267230",
            "name": "fname's Projects",
            "description": "",
            "projects": [
              "415080"
            ],
            "applications": [],
            "f_managed": true
          },
          ...
    

    f_managed: user can create projects or move them only into managed groups

    /projects

    GET

    /projects - returns the same data as /sessions/current:GET request returns except user_id. You may pass "f_recent_projects_ids=1" GET parameter, then the response will contain 'recent_project_ids' array with recently visited projects ids (the same as on projects dashboard). Order is from most recently visited to less recently. Only projects visited using web UI are marked as recent. Avoid of using f_recent_projects_ids too often (for example more than once in hour).

    /projects/project_id - returns the same data as /sessions/current:GET request returns except:  

        1) user_id is not returned;

        2) "projects" array contains only specified project (or it's empty if a project is not found)

        3) project inside "projects" array has additional field "notifications", containing all unread notifications. See /notifications for "notifications" structure description.

        4) project inside "projects" array has an additional field "f_subtasks_adv", containing boolean true or false. It reflects if a user is able to create advanced subtasks in the project.

    POST

    Input data: 

    name description
    project_name may be empty if f_first = 1 (default will be used)
    project_description may be empty
    project_color may be empty or contain HEX number (w/o "#")
    todo_view_type     kanban|default, so far use "default" value
    f_first if this project is created right after signup, should be true, false otherwise
    group_id project group. If empty, group_name should be set
    group_name if is not empty, will be created a new group with this name (passed group_id will be ignored). When f_first is true, both group_id and group_name may be empty - default group will be created. Otherwise, an error will be triggered.
    changed_users list of invitations to users. Maybe empty or absent. See projects/project_id:PUT for structure description (only "added" users will be processed)

    Example

    {  
       "project_name":"Name",
       "project_description":"Some descr",
       "project_color":"34ad22",
       "todo_view_type":"kanban",
       "f_first":true,
       "group_id":"",
       "group_name":"new group",
       "changed_users":{  
          "added":[  
             {  
                "row_id":"any_id_to_link_validation_to_email",
                "email":"some_email",
                "first_name":"fir!!st_name",
                "last_name":"last!!_name"
             },
             {  
                "row_id":"any_id_to_link_validation_to_email",
                "email":"some_email",
                "first_name":"first_name2",
                "last_name":"last_name2"
             }
          ]
       }
    }

    Output (inside 'data'): the same as for /projects/project_id:GET

    PUT

    (actual request should be /projects/project_id:POST)

    Input data: 

    name description
    project_name mandatory
    project_description may be empty
    project_color mandatory
    group_id mandatory if group_name is empty
    group_name mandatory if group_id is empty. If present, group_id is ignored
    f_active optional. Possible values: true|false. If present will change project state according to the value.
    changed_users list of added, deleted and updated users (though you do not need updated so far). It can be empty or absent. See projects/project_id:PUT for structure description.

    Changed users structure example is below:

    {
    	"added": [{
    		"row_id": "any_id_to_link_validation_to_email",
    		"email": "some_email",
    		"first_name": "fir!!st_name",
    		"last_name": "last!!_name"
    	}],
    	"updated": [{
    		"user_id": "309953",
    		"team_id": "7000"
    	}],
    	"deleted": [{
    		"user_id": "377131"
    	}, {
    		"user_id": "377132"
    	}]
    }

    Fields for an element inside added:

    name description
    row_id invitation id (generated by client app) - if this invitation is in error, id will be used to link error to the invitation in the response
    email mandatory
    first_name may be empty
    last_name may be empty

    Fields for an element inside updated:

    name description
    user_id  mandatory
    team_id  the same as role_id (later role_id where it present will be team_id). This is the only field available for editing.

    Fields for an element inside deleted:

    name description
    user_id  mandatory

    Example of /projects/project_id:POST request:

    {
    	"project_name": "Name",
    	"project_description": "Some descr",
    	"project_color": "34ad22",
    	"todo_view_type": "kanban",
    	"f_first": true,
    	"group_id": "267282",
    	"group_name": "new group",
    	"changed_users": {
    		"updated": [{
    			"user_id": "309953",
    			"team_id": "7000"
    		}],
    		"deleted": [{
    			"user_id": "377131"
    		}, {
    			"user_id": "377132"
    		}]
    	}
    }

    Output (inside 'data'): the same as for /projects/project_id:GET

    DELETE

    WARNING: Is not supported now

    /projects/project_id:DELETE

    /invitations

    GET

    /invitations - returns the list of all user's pending invitations to projects. Each element contains group_name, project_name, hash, and invited_by_user fields. 

    invited_by_user has the same structure as user array structure returned by /users:GET request. Note that email is always NULL. 

    The API endpoint returns extended data (instead of just project_id and invited_by_id) as a user is not yet a part of any project. Information for such invited user can't be obtained by standard /projects and /users requests.

    Example:

    "invitations": [
          {
            "group_name": "Some group",
            "project_name": "Some project",
            "hash": "f543a44968d5214c7511e071be0f6ec4",
            "invited_by_user": {
              "user_id": "1231122",
              "first_name": "bear_d",
              "last_name": "",
              "avatar_url": "http://some_url",
              "full_name": "bear_d",
              "email": null,
              "timezone": "Europe/Athens"
            }
          }
        ]

    PUT

    (actual request should be /invitations:POST)

    Input data: an array of objects with hash and action keys

    name description
    hash  invitation hash you get by /invitations:GET
    action  what to do with the invitation. Possible actions are 'accept' and 'decline'.

    Request data example:

    {
    	"invitations": [{
    		"hash": "bc4fcff30a99d7524ef36855a95f54a8",
    		"action": "accept"
    	}, {
    		"hash": "aaafcff30a99d7524ebbb855a95f54a8",
    		"action": "decline"
    	}]
    }

    Output: the same as for /invitations:GET

    /users

    GET

    Input data:

    /users - returns all users visible to the current user

    /users/current - returns current user data

    /users/user_id  - returns "users" array containing only specified user data, if the current user has permissions to see him. Empty "users" array otherwise

    Output:

    users: array with requested users data. Structure example:

        "users": {
          [
            "user_id": "132942",
            "first_name": "f",
            "last_name": "",
            "avatar_url": "https:\\/\\/freedcamp-avatars-test.s3.amazonaws.com\\/4b322be59237277135526b97d1e86de2.jpg",
            "full_name": "f",
            "email": "bear@test.com",
            "timezone": "America/New_York"
          ],
          [
            "user_id": "132944",
            "first_name": "fsdc",
            "last_name": "sdcd",
            "avatar_url": "https:\\/\\/freedcamp-avatars-test.s3.amazonaws.com\\/4b33322be59237277135526b97d1e86de2.jpg",
            "full_name": "f s.",
            "email": null,
            "timezone": "America/New_York"
          ],
          ...

    Note: "email" field is null if requesting user does not have permissions to see it.

    POST

    Input data: email, password, first_name, last_name, oauth_provider, oauth_id (inside the data), additional form FILE field - avatar file.

    name description
    email required
    password  may be empty in a case when oauth_provider parameter is passed
    first_name required
    last_name  may be empty
    oauth_provider if a user has done an unsuccessful login attempt using OAuth provider previously, an app may fill this field and oauth_uid field with appropriate data to get user linked with the provider right after the registration. If OAuth provider has provided the app with email and first name, you can directly issue this request with an empty password (will be generated on the server side) without displaying a register screen to the user. Note that in case of returned errors (like empty email field) these errors will still correspond to register screen. A field may be empty or absent.
    oauth_uid  OAuth provider unique user id. Should be present if oauth_provider is set, may be empty or absent otherwise
    mobile_app_version a version of the mobile app

    To the avatar attached, - note, max available square portion of the image will be used as an avatar (will be used central part of the image), and it will be resized to 100*100 px.

    X-API-TOKEN should be empty.

    Example:

    data: {"email": "bear+ss@deepshiftlabs.com", "password": "1111111111", "first_name": "fname", "last_name": "sdc"}

    avatar: binary file data*

    * i. e. request body contains 2 fields, string "data" and file "avatar", encoded as a form-data

    Output: the same as /sessions:POST returns

    PUT

    (actual request should be /users/current:POST)

    Input data: 

    name description
    email may be empty or absent. If present and differes from the current one, confirmation_password should be passed.
    password  SHOULD be empty or absent if user does not change it. If passed, confirmation_password should be passed also.
    first_name Can not be empty
    last_name  May be empty
    confirmation_password Active password, should be passed only when email or/and password are changed
    timezone User's timezone. To get a list of available timezones, use /timezones:GET

    To update avatar, use /avatars/current:POST.

    Request data example:

    {
    	"email": "some@freedcamp.com",
    	"password": "",
    	"first_name": "333",
    	"last_name": "44444",
    	"confirmation_password": "",
    	"timezone": "America/New_York"
    }

    Output: the same as for /users/user_id:GET, also may contain token (see below).

    WARN! If email and/or password is changed, a user will be logged out from all devices, including the current one (current token becomes invalid). So if a token is returned in the response, an application SHOULD replace the old token with this new one. Output example with a token is below. When different tokens for different sessions are implemented, a token will not become obsolete.

      "data": {
        "users": [
          {...}
        ],
        "token": "cc76fec61451717732153334d7e986acb380fcb2"
      }

    DELETE

    See /wipe for user deletion.

    /wipe

    /wipe/current

    GET

    WARN: Not allowed publicly for now

    is used to get information about account before deleting it. Currently, it returns the only flag f_password_needed.

    Output data:

    name description
    f_password_needed true or false. Not active or accounts created recently may be deleted w/o password confirmation, so you should check f_password_needed and do not ask the user for a password confirmation if it's false.

    Output example:

      "data": {
        "f_password_needed": true
      }

    POST

    WARN: Not allowed publicly for now

    is used to delete a user account and all linked data

    Input data:

    name description
    password  confirmation password. Maybe empty or absent if f_password_needed returned by /wipe:GET is false

    Input example:

        {"password": "11111111"}
    
    

    /password_reset_emails

    POST

    If successfull, an email to the given email will be sent with the reset key inside which should be used in /passwords:POST request then

    Input data: email

    Example:

    {"email": "xxx@xxxxx.com"}

    Output (inside 'data'):

    msg: Message you may show to user, like "Reset key has been sent to xxx@xxx.com"

    /passwords

    Allows to set a new password using reset password key sent by issuing /password_reset_emails:POST request

    POST

    Input data:

    password: new password.

    name description
    reset_key password reset key from the email

    Example:

    {"password": "11111111", "reset_key": "xxx"}
    

    /avatars

    POST

    I plan to use only POST requests for all actions related to files uploading because of PUT limitations in PHP when working with files. That's why avatar update is not under the /users/current:PUT request.

    Input data: 

    form FILE field - binary avatar file (not inside the data parameter with JSON)

    example:

    avatar: binary file data*

    * request body should be encoded as a form-data

    Output:

    avatar: an object which contains new avatar URL. Example:

        "avatar": {
          "avatar_url": "https:\\/\\/freedcamp-avatars-test.s3.amazonaws.com\\/4b322be59235557135526b97d1e86de2.jpg"
        }
    

    DELETE

    Use /avatars/current to reset the avatar to a default generated an image.

    Output: the same as for /avatars/current:POST.

    /notifications

    GET

    /notifications - returns "notifications" array inside data for all projects. WARN - may be slow, so avoid to call it too often.

    /notifications/project_id - returns "notifications" array inside data for given project id.

    Filtration

    By default, you get all notifications or all unread notifications in the project. To get unread notifications only for the items you are following (equal to "Things I follow" filter in web UI), pass a following=1 parameter:

    /notifications?following=1 or /notifications/project_id?following=1.

    Output:

    notifications: Array of items with unread actions for the specified project. Maybe later will contain read notifications as well. Example:

        "notifications": [
              {
                "project_id": "344",
                "item_u_key": "267220_415075_2_488",
                "app_id": "2",
                "item_id": "488",
                "item_title": "sdfvsdvsdvf",
                "f_read": false,
                "last_action_ts": 1438178379,
                "actions": [
                  {
                    "description_raw": "bear2 b. added todo.",
                    "description": "bear2 b. added todo.",
                    "action_ts": 1439569606,
                    "action_type": 1
                  }
                ]
              },
              {
                "project_id": "344",
                "item_u_key": "267220_415075_2_487",
                "app_id": "2",
                "item_id": "487",
                "item_title": "tergertg",
                "f_read": false,
                "last_action_ts": 1438178379,
                "actions": [
                  {
                    "description_raw": "bear2 b. <p>said</p>: фscasdc<br />\n",
                    "description": "bear2 b. said: фscasdc\n ",
                    "action_ts": 1439569566,
                    "action_type": 9
                  },
                  {
                    "description_raw": "bearr s. added todo.",
                    "description": "bearr s. added todo.",
                    "action_ts": 1439551062,
                    "action_type": 1
                  }
                ]
    name description
    project_id project id of notification
    item_u_key id for item notifications, use it for "mark as read" request
    f_read  is always true as now we return only unread notifications
    last_action_ts used for setting item as read to determine if a user has seen the actual version
    actions  an array of actions, more recent actions first. "description_raw" may contain HTML tags, they are stripped in "description" field.
    action_type see types list in the Constants wiki

    PUT

    (actual request should be /notifications:POST)

    Input data: 

    name description
    new_state  new state of notifications, possible values - read|unread
    items  an array of items to apply the state to.

    Structure of items array:
    item_u_key 
    last_action_ts

    Request data example:

    {
    	"new_state": "read",
    	"items": [{
    		"item_u_key": "267200_415044_2_2034232",
    		"last_action_ts": "425235345"
    	}]
    }

    /validations

    GET

    /notifications/email - checks if email used for an invitation is valid and does not exist in the project, also returns avatar URL if check passed. Probably these actions will be split/moved to different API URLs after discussions.

    "email" in URL means a type of validation. 

    Input:

    name description
    email email to validate
    project_id optional. If set, an output will contain an error if the email is already present in the project users

    Request example: 

        data:   {"email": "", "project_id": "423242"}

    Output:

    avatar_url - on success

    Example:

        "avatar_url": "https://freedcamp-avatars-test.s3.amazonaws.com/534d29407bfce199827779dbb4b4a3c8e_6eabef.png"

    /tasks

    GET

    /tasks - returns a list of all tasks user has access to

    /tasks/?project_id=xxx - list of tasks in the project

    /tasks/task_id - list of tasks which contains only the task with given task_id

    Custom fields

    To include custom fields data in the response you need to add "f_cf=1" parameter, example: /tasks/?project_id=xxx&f_cf=1. Only fetch is supported for custom fields (no insert/update/delete). When you pass f_cf=1, the response will contain an additional array of custom fields templates used in the resulting task list.

    Limits

    All /tasks:GET requests support limit and offset parameters. Example: "/tasks?limit=2&offset=2". Current default (and maximum allowed) limit for public API is 200.

    All responses contain "meta" field:

        "meta": {
            "has_more": true, // always presents
            "total_count": 1362 // presents if has_more = true
        }
    name description
    has_more is true if there are more results than were returned in the response, and false otherwise.
    total_count presents if show_more = true and contains all available results.

    WARN: currently limit, offset, total_count values are applied to the top-level tasks. All subtasks are ignored when a limit is applied, and total_count is calculated.

    Filtration and order

    /tasks and /tasks/?project_id=xxx requests support filtration and ordering. Filters/order may be applied in any combination.

    Supported filters:

    name description
    status check constants wiki for possible values. For example, to get only not started and started tasks, you should use:  "/tasks?status[]=0&status[]=2"
    assigned_to_id accepts integer values containing user id or one of Assignments constants from constants wiki
    created_by_id accepts integer values containing user id
    due_date[from] accepts a date in format YYYY-MM-DD. If set, only tasks with the due date set and due date >= due_date[from] will be returned
    f_with_archived

    accepts 1/0 values. If 1 is passed, tasks from archived projects will be included to the response. If omitted or 0 is passed, only tasks from active projects are fetched.

    Supported orders: 

    priority: tasks with no priority set are supposed to have the lowest priority.
    due_date: tasks with no due date set are always placed at the list end despite the order direction.

    WARN: if there are many orders in the request, only the first one will be applied.
    WARN: ordering is applied to Tasks groups for all orders except due_date. So if you have two tasks groups in output, there will be all tasks from the first group, and then all tasks from the second group in the output. For due_date order, Tasks groups order is ignored.
    WARN: when ordering, subtasks are always following their parent tasks if these tasks are present in the output.

    If not valid filter or order value is passed, this value is ignored.

    Example: /tasks?status[]=0&due_date[from]=2017-02-01&due_date[to]=2017-02-28&assigned_to_id[]=13&assigned_to_id[]=-1&assigned_to_id[]=0&created_by_id[]=15&order[due_date]=asc

    Output example for /tasks:GET:

    Output:

    tasks: list of tasks with the next fields:

    name description
    id task id
    assigned_to_id user id task is assigned to. May have values -1 (ASSIGNED_EVERYONE) and 0 (ASSIGNED_NOONE).
    created_by_id user id who created the task
    task_group_id
    project_id
    priority possible values: 0 (none), 1 (low), 2 (medium), 3 (high). See also 'priority_title' field - will discuss with Dima how to pass constants like these to the client better
    title
    description raw description, with Freedcamp tags like. WARN - you should show this data to the user when editing.
    description_processed (absent if it's not a get one task by id) processed description, where [fcattach] tags are replaced with actual images with link. WARN - is present only when you request only one task, absent otherwise. You should show to user this data when showing task (and use raw "description" when editing).
    status one of the next values: 0 (not started), 1 (completed), 2 (in progress)
    comments_count
    files_count files attached to the task (files attached to task comments are not counted)
    completed_ts if was completed, ts when it happened, null otherwise
    start_ts null if was not set
    due_ts null if was not set
    created_ts
    task_group_name
    priority_title a title of the corresponding value in 'priority' field
    status_title title of corresponding value in 'status' field
    assigned_to_fullname name of user task is assigned to (will be discussed if we need it and in what format)
    can_delete (absent if query is for more than one project)
    can_edit  (absent if query is for more than one project)
    can_assign  (absent if query is for more than one project)
    can_progress  (absent if query is for more than one project)
    can_comment  (absent if query is for more than one project)
    comments  (absent if it's not a get task by id) list of comments. Comments structure is described below
    files (absent if it's not a get task by id) list of files attached to the task. See /files:GET for structure description
    url url to the task
    cf_tpl_id custom fields template id (if linked with the task)
    custom_fields (absent if custom fields are not requested) array of custom fields values used for the task
    h_level shows the task nesting level, 0 for top level tasks.
    h_parent_id shows the parent task id. Is an empty string for top level tasks.
    h_top_id shows the top parent task id (so is equal to h_parent_id for subtasks with h_level=1, and differs for subtasks with h_level > 1). Is an empty string for top level tasks.
    order set by user order inside tasks group (using d&d). By default tasks in output are ordered by this field inside their tasks groups.

    WARN! It's possible that several tasks inside the same group have the same order value including default value (0).

    WARN! It's possible that subtask has an order equal or greater than its parent(s). In this case, API ignores the order of subtask and places subtask after parent task (if parent is present in output).

    WARN ! This field is NOT equal to the task position in the returned list.

    f_adv_subtask (absent if it's not a get one task by id) shows if this is an advanced subtask or not. True for adanced subtasks, false for usual tasks and not advanced subtasks. Advanced subtasks has the same properties (all editable) that usual tasks. Not advanced subtasks has title and status only, and status can be set only in "TODO_NOT_STARTED" or "TODO_COMPLETED" (no "TODO_IN_PROGRESS" status).  Not advanced subtasks can't have comments as well. It's possible for user to have access to both advanced and not advanced subtasks at the same time even inside the same project.

    Example:

        "tasks": [
          {
            "id": "1528",
            "h_parent_id": "1525",
            "h_top_id": "1524",
            "h_level": "2",
            "f_adv_subtask": false, // only presents for getting a task by id
            "assigned_to_id": null,
            "created_by_id": "167",
            "task_group_id": "272",
            "project_id": "305",
            "priority": 0,
            "title": "tngfng",
            "description": "<p>пат<br />\n </p>\n",
            "status": 0,
            "order": 3,
            "comments_count": 0,
            "files_count": 0,
            "completed_ts": null,
            "start_ts": null,
            "due_ts": 1440745200,
            "created_ts": 1440686274,
            "task_group_name": "new",
            "priority_title": "none",
            "status_title": "no progress",
            "assigned_to_fullname": "",
            "can_delete": true,
            "can_edit": true,
            "can_assign": true,
            "can_progress": true,
            "can_comment": true,
            "comments": [{...}, {...}, ...],
            "files": [{...}, {...}, ...],
            "url": "https://freedcamp.com/somename_LxR/project_Devel_yOf/todos/7666346/",
            "cf_tpl_id": "15",
            "custom_fields": [
                {
                    "cf_id": "18",
                    "value": "211"
                },
                {
                    "cf_id": "19",
                    "value": "1"
                }
            ]
          },
          ....
        ]

    Comments structure: the same as /comments:POST returns.

    If custom fields data is requested and there were custom fields templates linked to some tasks in the list, list of these templates will be returned in a separate array "cf_templates".
    Here is an example of its structure:

    "cf_templates": [
        {
            "id": "17",
            "title": "all fields",
            "fields": [
                {
                    "id": "20",
                    "title": "drop very long name",
                    "type": "dropdown",
                    "f_required": false,
                    "order": 0,
                    "dd_options": [
                        "the first option",
                        "the second option",
                    ]
                },
                {
                    "id": "1",
                    "title": "text",
                    "type": "text_field",
                    "f_required": false,
                    "order": 1,
                    "dd_options": null
                },
                {
                    "id": "2",
                    "title": "area",
                    "type": "textarea",
                    "f_required": false,
                    "order": 2,
                    "dd_options": null
                },
                {
                    "id": "19",
                    "title": "check",
                    "type": "checkbox",
                    "f_required": false,
                    "order": 3,
                    "dd_options": null
                },
                {
                    "id": "18",
                    "title": "numn",
                    "type": "number",
                    "f_required": false,
                    "order": 4,
                    "dd_options": null
                },
                {
                    "id": "17",
                    "title": "date",
                    "type": "date",
                    "f_required": false,
                    "order": 5,
                    "dd_options": null
                }
            ]
        }
    ]

    dd_options array contains values for the dropdown type of custom field. For other field types this field is set to null. Inside "custom_fields" array with values for the task, value for the field with dropdown type is the number of the value in the dd_options array (starting from 0). Also for dropdowns there is an additional field dd_actual_value which contains the actual value (so you may know it without extractin it from dd_options by id).

    POST

    Input data: 

    name description
    title
    description  may be empty string
    project_id
    task_group_id may be empty or absent if task_group_name is passed
    task_group_name  if passed, task_group_id is ignored, and new tasks group with this name will be created
    task_group_description  will be used if task_group_name passed, may be empty string
    priority  priority id. See priorities for :get.
    assigned_to_id should contain assigned to user id OR one of the two constants:  -1 (ASSIGNED_EVERYONE) and 0 (ASSIGNED_NOONE)
    due_date  may be empty or absent, format is YYYY-MM-DD (may be discussed)
    attached_ids  array of files uploaded previously with temporary=1 flag
    item_parent_id  may be absent or empty. Contains parent task id. Note: parent task should be in the same tasks group as passed task_group_id. Warn: if project where subtask is added to does not allow advanced subtasks (i.e. has f_subtasks_adv = false, see above), added subtask should contain empty string for description and due_date fields, and "0" for priority and assigned_to_id fields. Also the parent task should not be a subtasks. If case when other values are passed, they will be implicitly fixed to the right values with triggering an error sent to Freedcamp developers.

    Request example:

    {"title": "22222", "description": "wwwwwww", "project_id": "305", "task_group_id": "272", "task_group_name": "","task_group_description": "", "priority": "1", "assigned_to_id": "1", "due_date": "2015-08-28", "attached_ids": [1296, 1297]}

    Output: the same as /tasks/task_id:GET

    PUT

    (actual request should be /tasks/task_id:POST)

    WARN! If edited task is a subtask (h_parent_id is not empty) and has f_adv_subtask = false, edited data should contain empty string for description and due_date fields, and "0" for priority and assigned_to_id fields. Also the parent task should not be a subtasks. No limits if f_adv_subtask = true.

    Input data: 

    The same as for /tasks:POST except one additional compulsory field:

    status - status id. See statuses for :get,

    and except an additional notes for the item_parent_id field:

    item_parent_id - may be absent or empty. If is absent, current parent id value is not changed during the query. If is not empty and edited task is not a subtask, it becomes a subtask. If is empty and edited task is a subtask, it becomes a task. All children tasks of the edited task are still its children in any case. Note: parent task should be in the same tasks group as passed task_group_id. 

    Request data example:

        {"title": "QQrgfbQQfdvQ!!!!", "description": "dvsdvdsfvdfv", "task_group_id": "276", "task_group_name": "g", "task_group_description": "", "priority": "2", "assigned_to_id": "123", "due_date": "2015-08-13", "status": "2", "attached_ids": [1296, 1297]}

    Output: the same as /tasks/task_id:GET

    DELETE

    /tasks/task_id:DELETE

    /tasks_groups

    GET

    /tasks_groups/project_id - returns the list of the active (not archived) project's task groups

    Output:

    tasks_groups: list of tasks groups with the next fields:

    name description
    id tasks group id
    name name of the task group
    description description, may be empty
    order order of the tasks group inside the project, starting from 0
    project_id project is of the tasks group

    Example:

    "tasks_groups": [
          {
            "id": "156",
            "name": "Task list",
            "description": "",
            "order": 0,
            "project_id": "415173"
          },
          ...
        ]
    

    /files

    GET

    /files/file_id - returns requested file inside files array

    Output:

    files: list of files with the next fields:

    name description
    id file id
    name name of the file (as on user's PC when uploaded)
    url download url. Expires after some time, for example after 1 hour. May be absent or empty. Always presents if requesting one file, or files array is a part of item data like task or comment.
    thumb_url if f_image is true, contains thumbnail url, otherwise is null.
    size in bytes
    version_id
    first_version_id you may need it to upload newer version of the file is_last_version project_id
    files_group_id if file is inside some files group, it's id, "0" otherwise
    file_type file mime type
    app_id application to which file belongs to
    item_id item to which file attached to. May be "0".
    comment_id comment to which file attached to. May be "0".
    user_id user who uploaded the file
    f_temporary file was uploaded for item to be created (task, comment). You should pass file_id when submitting this item later to link it
    created_ts
    f_image if file is image or not. Images may have thumb_url filed filled

    Example:

    "files": [
          {
            "id": "1293",
            "name": "win.png",
            "url": "https://freedcampfilestorage_test.s3.amazonaws.com/dsfv_JiP/win-89617.png?AWSAccessKeyId=AKIAJMBJBCR6Y7ZBMEEA&Expires=1441557155&Signature=smKZNFrjlfWdtffr0ie2WIqbJDo%3D",
            "thumb_url": "https://freedcampfilestorage_test.s3.amazonaws.com/dsfv_JiP/win-89617_thumb.png?AWSAccessKeyId=AKIAJMBJBCR6Y7ZBMEEA&Expires=1441557155&Signature=0o3V5qojh2lCQofcvTN4K7%2FqGrk%3D",
            "size": 74197,
            "version_id": 1,
            "first_version_id": 1293,
            "is_last_version": true,
            "project_id": "316",
            "files_group_id": "0",
            "comments_count": 0,
            "file_type": "image/png",
            "app_id": "2",
            "item_id": "1549",
            "comment_id": "0",
            "user_id": "167",
            "f_temporary": false,
            "created_ts": 1441466810,
            "f_image": true
          },
          ....
     ]

    POST

    name description
    application_id should be always set
    project_id
    item_id may be empty if it's files application or file is temporary, otherwise should present (even for comments)
    comment_id my be empty if it's not attaching a file to comment or file is temporary
    temporary file is uploaded for item to be created (task, comment). You should pass returned file_id when submitting this item later to link it.

    file - additional form-encoded field (except JSON "data")

    Example:

    {"project_id": "309", "application_id": "2", "item_id": "1560", "comment_id": "514", "temporary":0}

    file: binary file data*

    * i. e. request body contains 2 fields, string "data" and file "avatar", encoded as a form-data

    Output: the same as /files/file_id:GET

    Note, that you should not attach files to items (tasks, comments etc) directly. So far it will cause wrong files_count counter for the item. It will be changed later.

    /timezones

    GET

    /timezones - returns all available timezones. You should use one of the ids to update user's timezone trough /users/current:PUT.

    Output:

    see example:

    "timezones": [
          {
            "id": "Pacific/Midway",
            "title": "UTC-11:00 Midway Island, Samoa"
          },
          {
            "id": "Pacific/Honolulu",
            "title": "UTC-10:00 Hawaii"
          },
        ....
    ]
    

    /comments

    POST

    Input data: 

    name description
    task_id
    project_id
    attached_ids  array of files uploaded previously with temporary=1 flag. May be empty or absent

    Example:

        {"task_id": "1549", "description": "wwwwwww", "attached_ids":[1307, 1297]}

    Output: 

    name description
    id
    description raw description, with FC tags like . WARN - you should show this data to user when editing.
    description_processed processed description, where [fcattach] tags are replaced with actual images with link. You should show to user this data when showing comment (and use raw "description" when editing).
    user_id  author id
    created_ts
    files list of files attached to the comment. See /files:GET for structure description
    can_edit boolean - if current user is able to edit the comment

    Note: for /comments:POST only just added comment will be returned.

    Example:

        "comments": [
              {
                "id": "515",
                "description": "<p>ghngfhnf<br />\n </p>",
                "description_processed": "<p>ghngfhnf<br />\n </p>",
                "user_id": "167",
                "created_ts": 1441478547,
                "files": [{...}, {...}, ...],
                "can_edit": false
              },
              ...
        ]

    PUT

    (actual request should be /comments/comment_id:POST)

    Input data: 


    description - comment description. May be empty or absent (equal to comment containing an empty string). Be sure to give a user a value of description field, not the description_processed field as the latter contains substituted FC tags like "" which should be preserverd.
     

    Example:

        {"description": "sdkjcnsdcsdc sdc  sdckjs dn"}

    Output: 

    The same as for /comments:POST

    DELETE

    /comments/comment_id

    Deletes the comment.

    /times

    GET

    /times returns Time application records

    Limits

    All /times:GET requests support limit and offset parameters. Example: "/times?limit=2&offset=2". Current default (and maximum allowed) limit for public API is 200.

    All responses contain "meta" field:

        "meta": {
            "has_more": true, // always presents
            "total_count": 1362 // presents if has_more = true
        }

    has_more is true if there are more results than were returned in the response, and false otherwise.
    total_count presents if show_more = true and contains all available results.

    Filtration and order

    /times and /times?project_id=xxx requests support filtration and ordering. Filters/order may be applied in any combination.

    Supported filters:

    name description
    assigned_to_id accepts integer values containing user id or one of Assignments constants from constants wiki.
    date[from] accepts a date in format YYYY-MM-DD. If set, only time records with the date set date >= due_date[from] will be returned.
    date[to] accepts a date in format YYYY-MM-DD. If set, only time records with the date set and <= due_date[to] will be returned.

    Supported orders: 

    date - orders by time record date

    WARN: if there are many orders in the request, only the first one will be applied.

    If not valid filter or order value is passed, this value is ignored.

    Example: /times?date[from]=2018-03-01&date[to]=2018-04-01&assigned_to_id[]=13&assigned_to_id[]=-1&order[date]=asc

    Output

    name description
    id
    project_id
    created_by_id  user id who created the record
    assigned_to_id  user id who is linked to the record
    description  description
    date_ts  selected date
    f_billed  if Time Record was billed in Invoices app
    minutes_count  how many minutes was worked
    created_ts  when the time record was created
    started_ts  if time record is started (i.e. timer is running), contains start timestamp. Current timer value is automatically added to minutes_count field.
    f_started  true is timer is running, false otherwise

    Example:

    "times": [
        {
            "id": "79",
            "project_id": "547",
            "created_by_id": "167",
            "assigned_to_id": "-1",
            "description": "4",
            "date_ts": 1521244800,
            "f_billed": false,
            "minutes_count": 1,
            "created_ts": 1521174531,
            "started_ts": null,
            "f_started": false
        },
        {
            "id": "81",
            "project_id": "547",
            "created_by_id": "167",
            "assigned_to_id": "167",
            "description": "assigned me",
            "date_ts": 1522195200,
            "f_billed": false,
            "minutes_count": 15,
            "created_ts": 1522131399,
            "started_ts": null,
            "f_started": false
        },
        {
            "id": "83",
            "project_id": "547",
            "created_by_id": "167",
            "assigned_to_id": "-1",
            "description": "assigned everyone",
            "date_ts": 1522368000,
            "f_billed": false,
            "minutes_count": 0,
            "created_ts": 1522131439,
            "started_ts": null,
            "f_started": false
        }
    ]

    Setting up Postman

    Postman will allow you to easily check and test all the available methods. Note that not all methods in the collection are currently allowed for access through public API (like /wipe).
    To get requests working for the example collection, you need to define 'xapikey' variable in the current Postman environment with the value of your api_key. No need to define cookie and xapitoken variables so far.
    For simple start you may use not-secured api_key - it does not requires calculating hash.

    If you want to use API key secured with API secret, you should define a pre-request script which will calculate hash based on current time. You should end up having set up like shown below.

    Url

    {{apihost}}/api/v1/tasks?api_key={{public_api_key}}&timestamp={{timestamp}}&hash={{hash}}&limit=5&offset=0

    Pre-request script

    var public_api_key = "your api key";
    var secret_key = "your api secret";
    var timestamp = new Date().valueOf();
    
    var hash = CryptoJS.HmacSHA1(public_api_key + timestamp, secret_key);
    
    // lines below will be a bit different for the standalone version - you'll use pm.environment.set("public_api_key", public_api_key);
    postman.setEnvironmentVariable("public_api_key", public_api_key);
    postman.setEnvironmentVariable("timestamp", timestamp);
    postman.setEnvironmentVariable("hash", hash.toString());

    Questions and bug reports

    Please send your questions and bug reports to help@freedcamp.com

    Feature requests

    Please post your feature requests on Freedcamp's UserVoice portal

    Found 1 of matches