If you are looking for the deprecated API v1 Documentation. Please download the PDF archive click here. For the Webhook Documentation click here. For archived blog posts here.

GET /users Getting Users

The following requests can be made to read users from TribeHR. (Support for create, update, and delete operations is in the works.)

The Users endpoint introduces the concept of comprehension between objects in TribeHR. Objects that are comprehended within another belong exclusively to that object. This is the case for Employee Records and Assignment Records - these objects only have meaning when associated with a User and not on their own. Because these objects are comprehended within Users, TribeHR’s API outputs full representations of these objects when a full representation of a User object is requested.

List active users

Includes all the active users in TribeHR (not terminated).

Users are output in the order in which they were created in TribeHR.

Request

  • The headers must include a valid authentication token.

GET /users.json X-API-Version: 2.0.0

Response

Status: 200 OK Content-Type: application/json [ { "id": 6, "username": "george", "email": "george@mycompany.com", "display_name": "George Black", "employee_record": { "first_name": "George", "last_name": "Black", "url": "/employee_records/47.json" }, "url": "/users/6.json" }, { "id": 7, "username": "alice", "email": "alice@mycompany.com", "display_name": "Alice McDonald", "employee_record": { "first_name": "Alice", "last_name": "McDonald", "url": "/employee_records/55.json" }, "url": "/users/7.json" } ]

Get Individual User

View details about an individual user

Request

  • The headers must include a valid authentication token.
  • :id paramerter is the integer identifier of the User you wish to get.

GET /users/{id}.json X-API-Version: 2.0.0

Response

Status: 200 OK Content-Type: application/json { "id": 7, "username": "alice", "api_key": "570675830ab61a31ef57f70ca335f64374b56281", "email": "alice@mycompany.com", "twitter_username": "alicemcdonald82", "linkedin_url": "http://ca.linkedin.com/in/alicemcdonald82/", "blog_url": "http://alice.blogger.com/", "display_name": "Alice McDonald", "avatar": { "url": "/users/view/7/picture" }, "created": "2012-10-25T09:46:53+00:00", "modified": "2013-07-22T15:18:02+00:00", "assignment_record": { "id": 100, "current": true, "employee_status": "ACTIVE", "full_time": true, "phone": "1 800 123 4567", "ext": 888, "employee_num": 15, "date_hired": "2012-10-25", "created": "2013-01-10T10:21:19+00:00", "modified": "2013-01-10T10:21:19+00:00", "job": { "id": 37, "title": "Software Engineer", "url": "/jobs/37.json" }, "department": { "id": 5, "name": "Development", "url": "/departments/5.json" }, "manager": { "id": 6, "username": "george", "email": "george@mycompany.com", "display_name": "George Black", "employee_record": { "first_name": "George", "last_name": "Black", "url": "/employee_records/47.json" }, "url": "/users/6.json" }, "employee_class": { "id": 7, "class": "Regular Employee" }, "location": { "id": 1, "name": "Silicon Valley", "url": "/locations/1.json" }, "url": "/assignment_records/100.json", "pay_info": { "type": "ANNUAL", "label": "Annual Salary", "rate": "65346.30", "currency": "USD" } }, "employee_record": { "id": 55, "effective_date": "2012-12-31", "current": true, "first_name": "Alice", "last_name": "McDonald", "middle_name": "Brenda", "phone": "1234567890", "address1": "260 Nowhere Avenue", "address2": "", "city": "San Francisco", "state": "CA", "country": "United States", "postal": "92500", "birthdate": "1982-02-21", "emergency_name": "John McDonald", "emergency_number": "0987654321", "created": "2012-12-31T15:35:19+00:00", "modified": "2012-12-31T15:35:19+00:00", "url": "/employee_records/55.json" }, "custom_field_records": [ { "id": "226", "content": "Lamborghini", "custom_field": { "id": 9, "name": "Company Car", "url": "/custom_fields/9.json" } }, { "id": "224", "content": "OS/2", "custom_field": { "id": 1, "name": "Favorite operating system", "url": "/custom_fields/1.json" } } ], "group": "Managers", "leave_usages": [ { "leave_type": { "id": 1, "name": "PTO", "accrual": "SEMIMONTHLY", "url": "/leave_types/1.json" }, "days_used": "5.0", "days_remaining": "5.0" }, { "leave_type": { "id": 2, "name": "Sick", "accrual": "NONE", "url": "/leave_types/2.json" }, "days_used": "1.0" } ], "badge_count": 0, "url": "/users/7.json" }

GET /leave_requests Getting Leave Requests

The following endpoint and options can be used to read leave request records from TribeHR. With the available filters, you should be able to support many workflows.

Note that it is currently the API consumer’s responsibility to calculate the number of working days (or hours) that the leave request represents. We are looking at changing this in the future.

List Leave Requests

Includes all leave requests in TribeHR, in the order in which they were created.

There are two optional querystring filers available for the listing of all leave requests:

  • status: Get only leave requests with the given current status. Options: "pending", "rejected", "approved", or ALL
  • filterByHasPermissionToApprove: String true or false. When true, only leave requests where the requester has full edit and approve permission will be returned

Request

Get all leave requests in TribeHR

GET /leave_requests.json X-API-Version: 2.0.0

GET /leave_requests.json?status=all X-API-Version: 2.0.0

Request

Get all APPROVED leave requests in TribeHR

GET /leave_requests/approved.json X-API-Version: 2.0.0

GET /leave_requests.json?status=approved X-API-Version: 2.0.0

Request

Get all PENDING leave requests in TribeHR

GET /leave_requests/pending.json X-API-Version: 2.0.0

GET /leave_requests.json?status=pending X-API-Version: 2.0.0

Request

Get all REJECTED leave requests in TribeHR

GET /leave_requests/rejected.json X-API-Version: 2.0.0

GET /leave_requests.json?status=rejected X-API-Version: 2.0.0

Response

Status: 200 OK Content-Type: application/json [ { "id": 17 "date_start": "2013-12-03" "date_end": "2013-12-04" "comments": "Headed to the beach!" "status": "APPROVED" "url": "/leave_requests/17.json" "user": { "id": "1" "username": "jstevens" "avatar": { "url": "/attachments/view/User/avatar/1" } "email": "jstevens@example.com" "display_name": "Jennifer Stevens" "assignment_record": { "current": true "url": "/assignment_records/176.json" } "employee_record": { "first_name": "Jennifer" "last_name": "Stevens" "url": "/employee_records/73.json" } "url": "/users/1.json" } "leave_type": { "id": 1 "name": "Vacation" "accrual": "BIWEEKLY" "url": "/leave_types/1.json" } }, { "id": 23 "date_start": "2013-12-11" "date_end": "2013-12-24" "comments": "Off to see the family" "status": "PENDING" "url": "/leave_requests/23.json" "user": { "id": "54" "username": "tsmith" "avatar": { "url": "/attachments/view/User/avatar/23" } "email": "tsmith@example.com" "display_name": "Tanya Smith" "assignment_record": { "current": true "url": "/assignment_records/192.json" } "employee_record": { "first_name": "Tanya" "last_name": "Smith" "url": "/employee_records/47.json" } "url": "/users/23.json" } "leave_type": { "id": 1 "name": "Vacation" "accrual": "BIWEEKLY" "url": "/leave_types/1.json" } } ]

POST /leave_requests Creating Leave Requests

Create a new leave request.

Note that it is currently the API consumer’s responsibility to calculate the number of working days (or hours) that the leave request represents. We are looking at changing this in the future.

TribeHR represents the length of time that an employee is away from work using a combination of days and hours. You must specify one the two fields; TribeHR will calculate the value of the other one automatically using the employee’s work hour records.

Request

Parameters:

  • :date_start (date; required) - the date of the first day of leave
  • :date_end (date; required) - the date of the last day of leave
  • :days (integer; either days or hours must be present, but not both) - the number of working days that this leave request represents. If hours is also present, the value of days will be ignored.
  • :hours (integer; either days or hours must be present, but not both) - the number of working hours that this leave request represents. If days is also present, its value will be ignored in favour of the value of hours.
  • :status (string; defaults to "PENDING") The status of the leave request. Users submitting a request on behalf of a subordinate may supply "PENDING" or "REJECTED" or "APPROVED"
  • :user[id] (integer; defaults to currently authenticated user) - the user to whom this leave request applies
  • :leave_type[id] (integer; required) - the ID of the type of leave being requested. See /leave_types.json
  • :comments (string) - Text written by the employee addressed to their manager

POST /leave_requests.json X-API-Version: 2.0.0 comments=I%27m%20off%20to%20visit%20my%20family%20in%20Ottawa%21& date_start=2013-11-15& date_end=2013-11-18& days=2& status=pending& user%5Bid%5D=20& leave_type%5Bid%5D=1

Response

Status: 200 OK { "id": 34, "comments": "I'm off to visit my family in Ottawa!", "date_start": "2013-11-15", "date_end": "2013-11-18", "days": 2, "hours": 11, "status": "PENDING", "created": "2013-10-16T21:22:12+00:00", "modified": "2013-10-16T21:22:12+00:00", "url": "/leave_requests/34.json", "user": { "id": 20, "username": "salleyfitzgibbon", "email": "devnull+salleyfitzgibbon@tribehr.com", "display_name": "Salley Fitzgibbon", "employee_record": { "first_name": "Salley", "last_name": "Fitzgibbon", "url": "/employee_records/51.json" }, "url": "/users/20.json" }, "leave_type": { "id": 1, "name": "Vacation", "accrual": "BIWEEKLY", "url": "/leave_types/1.json" } }

PUT /leave_requests Modifying Leave Requests

Modify an existing Leave Request. Supports all of the same parameters as the POST request above, but you must incldue an :id parameter that matches the ID in the URL.

Similarly to POST requests against /leave_requests.json, if both :hours and :days are set, :days will be ignored in favour of the value of :hours.

The exmaple request here approves a currently-pending leave request.

Request

PUT /leave_requests/{id}.json X-API-Version: 2.0.0 id=1&status=APPROVED

Response

Status: 200 OK Content-Type: application/json; charset=UTF-8 { "id": 1, "comments": "My cousin is getting married!", "date_start": "2013-10-25", "date_end": "2013-10-28", "days": 2, "hours": 16, "status": "APPROVED", "created": "2012-05-09T14:46:03+00:00", "modified": "2013-10-18T18:48:33+00:00", "url": "/leave_requests/1.json", "user": { "id": 2, "username": "emma", "email": "emma@tribehr.com", "display_name": "Emma Employee", "employee_record": { "first_name": "Emma", "last_name": "Employee", "url": "/employee_records/2.json" }, "url": "/users/2.json" }, "leave_type": { "id": 1, "name": "Vacation", "accrual": "NONE", "url": "/leave_types/1.json" } }

GET /events Getting Events

Request

  • The :notes field is a Rich Text field, but currently does not support BBCode. Therefore, the :notes field may return an HTML string, but API consumers should only use plain text in POST and PUT requests.
  • Includes events that are currently ongoing (their start date is in the past but their end date is in the future) and events that start in the future.
  • Events are sorted by start date, and the response contains all “upcoming” events (as defined above) or the 50 soonest “upcoming” events, whichever is less.

/events.json is an alias to this API endpoint.

GET /events/upcoming.json X-API-Version: 2.0.0

Response

Status: 200 OK Content-Type: application/json [ { "id": 20, "name": "Company Picnic", "start_date": "2013-08-29T11:00:00+00:00", "end_date": "2013-08-29T14:30:00+00:00", "notes": "<p>We'll have some BBQs on the lawn behind the building.</p>\r\n<p>Hope to see you there!</p>", "url": "/events/20.json", "event_type": { "id": 1, "name": "Lunch", "url": "/event_types/1.json" }, "locations": { "id": 3, "name": "London Office [Product and Development]", "url": "/locations/view/3.json" } }, { "id": 252, "name": "Product Launch", "start_date": "2013-08-30T17:00:00+00:00", "end_date": "2013-08-30T22:00:00+00:00", "notes": "<p>Spouses and significant others are welcome, too!</p>", "url": "/events/252.json", "event_type": { "id": 2, "name": "Company Gathering", "url": "/event_types/2.json" }, "locations": { "id": 3, "name": "London Office [Product and Development]", "url": "/locations/view/3.json" } } ]

Request

List events that have been marked as official holidays in TribeHR.

Events are sorted by start date ascending, and by default all holidays are returned.

Available Filters:

  • year (integer, optional) - you may provide a 4-digit year, to return only the events occuring in that year. Includes events which have at least one day in the given year.

GET /events/holidays.json?year=YYYY X-API-Version: 2.0.0

Response

Status: 200 OK Content-Type: application/json [ { "id": 12, "name": "New Year's Day", "notes": "<p>Official Holiday, no work.<\\/p>", "url": "/events/view/12", "start_date": "2013-01-01T00:00:00", "end_date": "2013-01-01T00:00:00", "event_type": { "id": 5, "name": "Official Holiday", "url": "/event_types/view/5.json" }, "locations": [ { "id": 2, "name": "Corporate Office [Headquarters] ", "url": "/locations/view/2.json" } ] }, { "id": 33, "name": "Boxing Day", "notes": "<p>Official Holiday, no work.<\\/p>", "url": "/events/view/33", "start_date": "2013-12-26T00:00:00", "end_date": "2013-12-26T00:00:00", "event_type": { "id": 5, "name": "Official Holiday", "url": "/event_types/view/5.json" }, "locations": [ { "id": 3, "name": "London Office [Product and Development]", "url": "/locations/view/3.json" } ] } ]

Request

View details about an individual event.

GET /events/{id}.json X-API-Version: 2.0.0

Response

Status: 200 OK Content-Type: application/json { "id": 252, "name": "Fun Family Event", "notes": "<p>Spouses and significant others are welcome, too!</p>", "is_official_holiday": false, "created": "2013-01-28T11:41:07+00:00", "modified": "2013-01-28T11:41:07+00:00", "url": "/events/view/12", "start_date": "2013-08-30T00:00:00", "end_date": "2013-08-30T00:00:00", "event_type": { "id": 5, "name": "Official Holiday", "url": "/event_types/view/5.json" }, "locations": [ { "id": 2, "name": "Corporate Office [Headquarters] ", "url": "/locations/view/2.json" } ] }

POST /events Create a New Event

Parameters:

  • name (string; required; must be at least two characters long) - the name of the event
  • notes (string; HTML allowed) - description or other text related to the event
  • start_date (date/time; required) - the date and time of the start of the event
  • end_date (date/time; required) - the date and time of the end of the event; must be later than the start date.
  • is_official_holiday (boolean; defaults to false) - whether this event should be excluded from leave request calculations
  • event_type[id] (integer; defaults to first event found in the system) - the ID of the type of event. (Event types are set up in the administration section of the TribeHR web app.)
  • location[][id] (integer; zero or more location[][id] parameters may be present) - the ID(s) of the locations to which this event applies. (Locations are set up in the administration section of the TribeHR web app.)

Request

POST /events.json X-API-Version: 2.0.0 name=New%20event& start_date=2013-08-30T17%3A00%3A00%2B00%3A00& end_date=2013-08-30T22%3A00%3A00%2B00%3A00& location[][id]=1& location[][id]=7& notes=HTML%20description%20of%20new%20event& is_official_holiday=1& event_type[id]=1

Response

Status: 200 OK Content-Type: application/json { "id": 254, "name": "New event", "start_date": "2013-08-30T17:00:00+00:00", "end_date": "2013-08-30T22:00:00+00:00", "notes": "HTML description of new event", "is_official_holiday": true, "created": "2013-08-19T18:02:04+00:00", "modified": "2013-08-19T18:02:04+00:00", "url": "/events/254.json", "event_type": { "id": 1, "name": "Lunch", "url": "/event_types/1.json" }, "locations": [ { "id": 1, "name": "Central Rental", "url": "/locations/1.json" }, { "id": 7, "name": "Headquarters", "url": "/locations/7.json" } ] }

PUT /events Modify an Event

Request

Modify an existing Event. Supports all of the same parameters as the POST request above, but you must include an :id parameter that matches the ID in the URL.

The example request here updates the name and start date of event #254.

PUT /events/{id}.json X-API-Version: 2.0.0 id=254& name=New%20event%20%28Updated%20Time%21%29& start_date=2013-08-30T18%3A00%3A00%2B00%3A00

Response

Status: 200 OK { "id": 254, "name": "New event (Updated Time!)", "start_date": "2013-08-30T18:00:00+00:00", "end_date": "2013-08-30T22:00:00+00:00", "notes": "HTML description of new event", "is_official_holiday": true, "created": "2013-08-19T18:02:04+00:00", "modified": "2013-08-19T18:30:35+00:00", "url": "/events/254.json", "event_type": { "id": 1, "name": "Lunch", "url": "/event_types/1.json" }, "locations": [ { "id": 1, "name": "Central Rental", "url": "/locations/1.json" }, { "id": 7, "name": "Headquarters", "url": "/locations/7.json" } ] }

GET /kudos Getting Kudos

Request

Note that the text field is a Rich Text field. (See the “Rich Text” section for details.) This means that when sending a request to /kudos.json or /kudos/{id}.json you may specify the query string parameter formattedTextAs=html if you wish to receive the text field as HTML instead of BBCode.

When sending a POST or PUT request to /kudos.json, you must specify the text field as plain text or BBCode. (Remember that TribeHR supports a subset of BBCode; see the “BBCode” section for details.)

Remember that :formattedTextAs has an effect on output only, but can be used on POST or PUT requests as well as GET requests in order to specify the output format.

List recently created kudos.

Includes up to 50 of the most recently created kudos. This request can take quite some time to run.

The picture resource (contained inside any kudos object that has an attached picture) provides a url property. You can fetch the image by treating url as relative to https://[subdomain].mytribehr.com/attachments/view.

GET /kudos.json?formattedTextAs=html X-API-Version: 2.0.0

Response

Status: 200 OK [ { "id": 83, "poster": { "id": 1, "username": "admin", "email": "admin@example.com", "display_name": "Tribe Admin", "employee_record": { "first_name": "Tribe", "last_name": "Admin", "url": "/employee_records/58.json" }, "url": "/users/1.json" }, "recipients": [ { "id": 17, "username": "willytrainer", "email": "willytrainer@example.com", "display_name": "Willy Trainer", "employee_record": { "first_name": "Willy", "last_name": "Trainer", "url": "/employee_records/55.json" }, "url": "/users/17.json" }, { "id": 6, "username": "abbyring", "email": "abbyring@example.com", "display_name": "Abby Ring", "employee_record": { "first_name": "Abby", "last_name": "Ring", "url": "/employee_records/46.json" }, "url": "/users/6.json" }, { "id": 16, "username": "salvatoredelnero", "email": "salvatoredelnero@example.com", "display_name": "Salvatore Delnero", "employee_record": { "first_name": "Salvatore", "last_name": "Delnero", "url": "/employee_records/23.json" }, "url": "/users/16.json" } ], "picture": { "url": "s3--pic_commitment-bccd5b21.jpg" }, "text": "<p>Great job pulling together to meet our iteration commitments!</p>", "comment_count": 2, "url": "/notes/83.json", "source": "web", "created": "2013-08-20T18:42:31+00:00" }, { "id": 82, "poster": { "id": 1, "username": "admin", "email": "admin@example.com", "display_name": "Tribe Admin", "employee_record": { "first_name": "Tribe", "last_name": "Admin", "url": "/employee_records/58.json" }, "url": "/users/1.json" }, "recipients": [ { "id": 20, "username": "salleyfitzgibbon", "email": "salleyfitzgibbon@example.com", "display_name": "Salley Fitzgibbon", "employee_record": { "first_name": "Salley", "last_name": "Fitzgibbon", "url": "/employee_records/51.json" }, "url": "/users/20.json" } ], "text": "<p>You did a great job on that presentation yesterday!</p>", "comment_count": 0, "url": "/notes/82.json", "source": "web", "created": "2013-08-17T18:42:39+00:00" } ]

Request

View details about an individual kudos

The :picture resource (contained inside the kudos if and only if it has an attached image) provides a :url property. You can fetch the image by treating url as relative to https://[subdomain].mytribehr.com/attachments/view.

GET /kudos/{id}.json?formattedTextAs=html X-API-Version: 2.0.0

Response

Status: 200 OK { "id": 83, "poster": { "id": 1, "username": "admin", "email": "devnull+admin@tribehr.com", "display_name": "Tribe Admin", "employee_record": { "first_name": "Tribe", "last_name": "Admin", "url": "/employee_records/58.json" }, "url": "/users/1.json" }, "recipients": [ { "id": 17, "username": "willytrainer", "email": "devnull+willytrainer@tribehr.com", "display_name": "Willy Trainer", "employee_record": { "first_name": "Willy", "last_name": "Trainer", "url": "/employee_records/55.json" }, "url": "/users/17.json" }, { "id": 6, "username": "abbyring", "email": "devnull+abbyring@tribehr.com", "display_name": "Abby Ring", "employee_record": { "first_name": "Abby", "last_name": "Ring", "url": "/employee_records/46.json" }, "url": "/users/6.json" }, { "id": 16, "username": "salvatoredelnero", "email": "devnull+salvatoredelnero@tribehr.com", "display_name": "Salvatore Delnero", "employee_record": { "first_name": "Salvatore", "last_name": "Delnero", "url": "/employee_records/23.json" }, "url": "/users/16.json" } ], "values": [ { "id": 10, "name": "Respect", "image": { "url": "respect/icon.png" }, "url": "/values/10.json" }, { "id": 11, "name": "Teamwork", "image": { "url": "teamwork/icon.png" }, "url": "/values/11.json" } ], "comments": [ { "id": 87, "comment": "You guys are great - no one even had to come in on the weekend!", "source": "web", "created": "2013-08-20T18:46:53+00:00", "modified": "2013-08-20T18:46:53+00:00", "url": "/comments/87.json", "poster": { "id": 2, "username": "emma", "email": "emma@tribehr.com", "display_name": "Emma Manager", "employee_record": { "first_name": "Emma", "last_name": "Manager", "url": "/employee_records/45.json" }, "url": "/users/2.json" } }, { "id": 88, "comment": "Hopefully it stays that way :) More slack time next iteration!", "source": "web", "created": "2013-08-20T18:47:31+00:00", "modified": "2013-08-20T18:47:31+00:00", "url": "/comments/88.json", "poster": { "id": 6, "username": "abbyring", "email": "devnull+abbyring@tribehr.com", "display_name": "Abby Ring", "employee_record": { "first_name": "Abby", "last_name": "Ring", "url": "/employee_records/46.json" }, "url": "/users/6.json" } } ], "picture": { "url": "s3--pic_commitment-bccd5b21.jpg" }, "text": "<p>Great job pulling together to meet our iteration commitments!</p>", "comment_count": 2, "url": "/notes/83.json", "source": "web", "created": "2013-08-20T18:42:43+00:00" }

POST /kudos Sending Kudos

Request

Parameters:

  • :recipients[][id] (integer; one or more :recipients[][id] parameters should be present) - the ID(s) of the recipients of this kudos
  • :text (string) - the text of the kudos
  • :picture (image) - a picture to attach to the kudos. To attach a picture to a kudos, you’ll need to send your request encoded as multipart/formdata. Your picture should be included in a part with the name :picture.
  • :values[][id] (integer; zero or more :values[][id] parameters may be present) - the ID(s) of any values that should be attached to this kudos

Each kudos should contain at least one of :text and :picture, although this is currently not enforced by the API. Likewise, at least one recipient should be listed, but again, this is not enforced. The poster of the kudos is assumed to be the user authenticated on this request; you should not specify the poster in your request.

POST /kudos.json?formattedTextAs=html X-API-Version: 2.0.0 X-Source: Awesome Kudos-Posting App recipients[][id]=6& recipients[][id]=17& text=You%27ve%20done%20a%20%3Ci%3Ewonderful%3C%2Fi%3E%20job%20recently.& values[][id]=11

Response

Status: 200 OK { "id": 88, "poster": { "id": 1, "username": "admin", "email": "devnull+admin@tribehr.com", "display_name": "Tribe Admin", "employee_record": { "first_name": "Tribe", "last_name": "Admin", "url": "/employee_records/58.json" }, "url": "/users/1.json" }, "recipients": [ { "id": 6, "username": "abbyring", "email": "devnull+abbyring@tribehr.com", "display_name": "Abby Ring", "employee_record": { "first_name": "Abby", "last_name": "Ring", "url": "/employee_records/46.json" }, "url": "/users/6.json" }, { "id": 17, "username": "willytrainer", "email": "devnull+willytrainer@tribehr.com", "display_name": "Willy Trainer", "employee_record": { "first_name": "Willy", "last_name": "Trainer", "url": "/employee_records/55.json" }, "url": "/users/17.json" } ], "values": [ { "id": 11, "name": "Teamwork", "image": { "url": "teamwork/icon.png" }, "url": "/values/11.json" } ], "text": "You've done a <i>wonderful</i> job recently.", "comment_count": 0, "url": "/notes/88.json", "source": "Awesome Kudos-Posting App", "created": "2013-08-20T20:05:18+00:00" }

PUT /kudos Modifying Kudos

Modify an existing Event. Supports all of the same parameters as the POST request above, but you must include an id parameter that matches the ID in the URL.

The example request here updates the text and clears the values of kudos #88.

```PUT /kudos/{id}.json?formattedTextAs=html X-API-Version: 2.0.0 text=Congratulations%20on%20your%20new%20certification.& values%5B%5D%5Bid%5D=& id=88

Status: 200 OK { "id": 88, "poster": { "id": 1, "username": "admin", "email": "devnull+admin@tribehr.com", "display_name": "Tribe Admin", "employee_record": { "first_name": "Tribe", "last_name": "Admin", "url": "/employee_records/58.json" }, "url": "/users/1.json" }, "recipients": [ { "id": 6, "username": "abbyring", "email": "devnull+abbyring@tribehr.com", "display_name": "Abby Ring", "employee_record": { "first_name": "Abby", "last_name": "Ring", "url": "/employee_records/46.json" }, "url": "/users/6.json" }, { "id": 17, "username": "willytrainer", "email": "devnull+willytrainer@tribehr.com", "display_name": "Willy Trainer", "employee_record": { "first_name": "Willy", "last_name": "Trainer", "url": "/employee_records/55.json" }, "url": "/users/17.json" } ], "text": "Congratulations on your new certification.", "comment_count": 0, "url": "/notes/88.json", "source": "Awesome Kudos-Posting App", "created": "2013-08-20T20:06:07+00:00" }

DELETE /[any resource]/{id} Deleting Resources

All resources are deleted in the same way - just send a DELETE request to a resource’s URL. DELETE requests may only be sent to URLs that represent a single item (such as /events/{id}.json) but may not be sent to URLs that represent collections of resources (such as /events.json). An example follows:

Request

DELETE /events/{id}.json X-API-Version: 2.0.0

Response

Status: 200 OK { "success": { "code": "DELETED", "messages": [ "Operation successfully completed." ] } }

Introduction

Introduction

Welcome to TribeHR’s API documentation. We provide a RESTful API in order for 3rd party integrations or apps to request or deliver data to the TribeHR web app. We are pleased to announce the availability of version 2.0 of our API, which is documented here. For information about our old API, which is currently still available, please refer to developers.tribehr.com/api.

Please be aware that this is not yet a fully released product and as such we are not able to provide full support yet. If you run into issues, however, feel free to contact support@tribehr.com, and we will do our best to help, although it may take a little longer than normal.

We welcome feedback on our API as well as this documentation - please feel free to comment on these pages or get in contact with us at support@tribehr.com

Versioning

The TribeHR API uses semantic versioning, which, in short, means that we use a three-part version string to specify the API version, such as 2.0.1. All changes to the API generate some change in the version number. Breaking changes increment the major version (2.0.1 ==> 3.0.0); non-breaking, functional changes result in an increment of the minor version (2.0.1 ==> 2.1.0); and bug fixes adjust the patch version (2.0.1 ==> 2.0.2).

We will be deprecating and eventually removing support for old API versions, but for now API v1 is still supported. Any deprecation/removal of support will be posted to our developer website so that you can react to any planned changes.

Version History

Current Version: 2.2.0

2.2.0

The url property is now in the correct format. For example, the URL for User ID 32 is now /users/32.json / /users/32.xml instead of /users/view/32. However, some URLs returned from the API may point at API endpoints which are not implemented.

2.1.0

A user’s avatar URL may sometimes be an absolute URL pointing directly to S3 instead of being a URL relative to TribeHR’s servers. Avatars with URLs pointing directly to S3 are guaranteed not to change as long as the S3 URL doesn’t change. Avatars with URLs pointing back to TribeHR servers may change at any time. This means that avatars served directly from S3 will have the dual benefit of being faster to download and easier to cache.

2.0.1

Changed the rules around visibility on the User resource’s group field. Users can now see their own group. If a user’s group is "Managers", they can see the group of all of the users they have permission to manage. (See “Permissions and Visibility” below.) If a user’s group is "Administrators", they can see the group of all users.

2.0.0

Brand new, revamped API!

Authentication

Each request must include the current user’s authentication details, encoded as HTTP Basic Authentication; that is, each request must include an Authorization: Basic xxxx header, where xxxx is the Base64 encoding of a string constructed as identifier:secret, where identifier is either the user’s username or email, and secret is either the user’s password or their API key.

We strongly suggest that you use a user’s API key to authenticate them, since it decreases the attack surface that a hacker can use to steal their password, which the user may be using on more than one site.

A user’s API key can be found on the edit page for their employee profile (https://[subdomain].mytribehr.com/users/edit/{user_id}/account). Alternatively, you can make an API request (authenticating using the user’s password, naturally) to /users/me.json?requireApiKey=true (as documented in the Users section, below). The response to this request will include the user’s API key, generating one automatically if they don’t already have one.

X-Source Header

Some of the resources available in the TribeHR API support the concept of a source - that is, they keep track of where they came from. TribeHR uses this functionality internally in order to apply “via TribeHR for iOS” tags to kudos and comments that originate from our iPhone app.

You can opt to send an X-Source header with your request in order to get similar treatment in TribeHR. Sources must represent the name of the consumer of the API, and may be any string; they must not change from request to request, and they must be identical for all users of the same API consumer or app.

The following resources support the X-Source header:

  • Kudos
  • Comments
  • Note: The source is applied to resources on their creation; sending an X-Source header with a PUT request does not change a resource’s source property.

Making API Requests

TribeHR differentiates API requests from regular web requests based on the end of the URL. TribeHR assumes that any request ending with .json or .xml is an API request; all other requests are treated as regular web requests and are returned as HTML.

All requests made against API v2 must include the X-API-Version header. Otherwise your request will be treated as an API v1 request, and you will miss out on improvements, modifications, and new features that will be made available in the future.

All requests must be made over HTTPS. Regular HTTP requests are automatically redirected to HTTPS but relying on this behaviour is a bad idea for security reasons.

XML vs JSON

The TribeHR API responds to requests with a response either formatted as JSON or XML. Both are supported equally, but for simplicity the rest of this documentation refers only to the JSON output. TribeHR decides which format to send you depending on the end of the URL you send. A URL ending in .json will return JSON; a URL ending in .xml will return XML.

Input to the API is always form-encoded, and never JSON or XML encoded.

Sending POST and PUT data

All PUT requests must include an id parameter in their body text, and it must match the ID specified in the request’s URL (See ID_MISMATCH in the Error Handling section).

All data that you send to TribeHR through the API is form-encoded. For most parameters, this is simple - just URL-escape your values and do regular form encoding:

PUT /users/53.json id=53&twitter_username=%40tribehr&blog_url=blog_url=http%3A%2F%2Fdevelopers.tribehr.com Sometimes you’ll need to specify values for sub-objects, such as modifying fields in a user’s assignment record. In this case you’ll need to use object[property] syntax as the key in your form-encoded request body. (The square brackets in the key should be URL-encoded.) In the following example, we modify a user’s phone number, which is part of their assignment record.

PUT /users/5.json id=5&assignment_record%5Bphone%5D=519-555-1234 In other cases, you will need to reference another resource when creating or updating a resource. For example, Events are associated with Event Types, which are defined in the administration section of the TribeHR web app. In this case, you should reference the existing resource’s ID, usually via a resource_name[id] key. In the case where you need to specify an array of existing resources (for instance, events can apply to zero or more locations, which are also defined in the administration section of the web app), you can use resource_name[][id] key. (Remember to URL-encode the square brackets!) The following example illustrates both cases, by specifying a single Event Type and multiple Locations.

PUT /events/252.json id=252&name=Updated%20Event&event_type%5Bid%5D=1&location%5B%5D%5Bid%5D=1&location%5B%5D%5Bid%5D=7

Differences between POST and PUT

POST requests create new items; PUT requests update existing ones.

POST requests are documented below with a list of parameters, some of which may be marked “required.” Unless otherwise documented, the corresponding PUT requests for each resource type support all of the same parameters as the POST request, but all parameters except for :id are optional (again, unless otherwise documented). If you leave a parameter out of a PUT request, it means that you do not wish to change the existing value.

Other validation constraints (such as “date X must occur before date Y”) still apply, and will take into account existing values for any parameters that are not included in the PUT request.

For example, if an Event with ID 53 already exists and has start date and end date set to Sept 1, 1:30pm and Sept 1, 2:30pm respectively, then sending the following PUT request that changes the start date will fail, since the end date would end up before the start date:

PUT /events/53.json id=53&start_date=2013-09-01T15:30:00+00:00

Remember: if you fail to supply id, or your id parameter does not match the ID in the URL, you will be returned a 400 HTTP response with an ID_MISMATCH error code. (See Error Handling, below.)

Data Types

We use the following data types in the documentation below as a shorthand. JSON technically only supports, strings, numbers, arrays, and objects, so the data types all map to these in some way.

  • Strings and numbers (integers and floating point numbers) can be represented natively in JSON, so no format translation is required
  • Rich text is represented by a BBCode string, or, optionally, an HTML string. See “Rich Text” below for details.
  • Booleans are represented in JSON responses as native true and false values, but when sending form-encoded requests to the API, they should be represented by integers; they must either be 0 or 1
  • Dates and Date/Times should be represented by strings adhering to ISO 8601 (details on W3.org)

A note on dates and date/times

TribeHR distinguishes between dates (formatted as 2013-09-30) and date/times (formatted as 2013-09-30T14:39:21+00:00), so make sure your parser is able to distinguish between the two. A common pitfall is to parse 2013-09-30 as “Midnight on Sept 30, 2013, UTC,” which when translated to the local time zone can unintentionally actually yield a different date.

Because of this, dates should be treated almost like a string literal - no time calculations should be performed on them; while date/times should be treated as usual and should be translated to the appropriate time zone before being displayed to the user.

Always-local date/times

Some dates in TribeHR are meant to be treated as always-local, regardless of where in the world a particular user is. For example, in the TribeHR web app, start and end date/times for Company Events do not have a time zone associated with them, and regardless of user or location, always show the exact same time of day for everyone. These are represented in the API by a slight modification on the ISO 8601 format, by omitting the time zone information at the end of the date string. For example: 2012-09-30T14:39:21

Rich Text

Some resources in TribeHR include rich text properties; for instance the text property of the kudos resource is a rich text field.

When sending data to the TribeHR API via a PUT or POST, the value that you send for a rich text field must either be a plaintext string or a BBCode string. We do not support API clients sending HTML strings to TribeHR. TribeHR supports a subset of all BBCode tags; see “BBCode” below for details.

When requesting resources that include rich text fields, you can include a formattedTextAs query parameter to specify how the rich text should be represented in the response. Valid values for this query parameter are html and bbcode, where bbcode is the default.

Note that formattedTextAs only has an effect on output. Input should always be plain text or BBCode.

BBCode

TribeHR supports a subset of all BBCode tags. The following tags are supported:

  • [b] - bold
  • [i] - italic
  • [u] - underline
  • [url] - hyperlink
  • [email] - mailto: hyperlink
  • [hr] - horizontal rule
  • [color] - font color
  • [size] - font size
  • [ul] - unordered list
  • [ol] - ordered list
  • [li] - list item
  • [left] - left-aligned block
  • [right] - right-aligned block
  • [center] - center-aligned block
  • [code] - text styled in monospace as “code”
  • [quote] - text styled as a blockquote

Error Handling

There are several error cases that you may come across while consuming the API. In each case you should receive a non-2XX HTTP response. In most cases you should receive body data that describes the error, in the same format, system-wide.

In some cases you may receive an error response with no body. For instance, if you make a request using a URL that does not map to a valid resource, you will receive a 404 response with no body. Similarly, if you make an unauthenticated request, you will receive a 401 response with no body.

Error responses provide an error object containing a single error code code (string) and an array messages of human-readable error messages (which contains zero or more messages).

We use the following error codes:

  • INVALID_ID - a single resource was requested but no ID was provided. Returned as part of a 404 (Not Found) response.
  • NOT_FOUND - a single resource was requested (for example, GET /events/123.json) but could not be found. Returned as part of a 404 (Not Found) response.
  • ID_MISMATCH - a POST or PUT request failed to save because the ID of the resource in the URL did not match the ID in the request body. Returned as part of a 400 (Bad Request) response.
  • DELETE_ERROR - an unknown error occurred while deleting a resource; the messages array may give some hints as to the reason.
  • SAVE_ERROR - an unknown error occurred while creating or updating a resource; the messages array may give some hints as to the reason.
  • VALIDATION_ERROR - a POST or PUT request failed because the data sent in the body was not valid. For instance, a required field may be missing or an end date may occure before a start date. The messages array should explain the invalid data to the user. Returned as part of a 400 (Bad Request) response.
  • RIGHTS_ERROR - indicates that the account (not the user; see “Users vs Accounts,” above) does not have this feature enabled in their package. Returned as part of a 403 (Forbidden) response.
  • ACCESS_ERROR - indicates that the current user doesn’t have permission to access the requested resource. Returned as part of a 403 (Forbidden) response.
  • CONNECTION_ERROR - indicates that TribeHR had trouble connecting to the account’s database. Returned as part of a 500 (Internal Server Error) response.
  • UNKNOWN_SUBDOMAIN - indicates that the account (not the user; see “Users vs Accounts”, above) could not be found. Returned as part of a 404 (Not Found) response.
  • MAINTENANCE - indicates that TribeHR is undergoing maintenance and will be back up and running later. Returned as part of a 503 (Service Unavailable) response.
  • ERROR - an unknown error occurred.

Examples

Requesting an item that doesn’t exist example:

GET /events/1234567.json X-API-Version: 2.0.0 Status: 404 Content-Type: application/json { “error”: { “code”: “NOT_FOUND”, “messages”: [ “Invalid Event” ] } } ```

Permissions and Visibility

All API requests are made on behalf of the user represented by the HTTP Basic Authentication information that is included in each request. All resources in TribeHR are subject to authorization and visibility checks. Some users will not have permission to see certain resources, and some users will have permission to see resources which have properties which they are not allowed to see.

Any information that the user does not have permission to see will be absent from any API requests.

This is in contrast to information that is present, but the value of which is empty or null. Empty or null data always means that the user has visibility on that data, but the value is literally empty or null.

User Groups

Each user is assigned to a particular group: Employees, Managers, or Administrators.

  • Administrators have access to all data in TribeHR.

  • Employees have access to all data whose privacy is marked “Everyone”. Employees also have access to data that is owned by them and marked as “Manager and Employee”.

  • Managers have access to all data whose privacy is marked “Everyone”. Managers also have access to data belonging to other users based on the management style.

Details about what information a given user has permission to see or act upon is documented in this FAQ.

Representations of Resources

All resources have exactly two representations that may be returned to you by the API: the full object, and the partial object.

All representations of resources are subject to visibility. An object will not be returned if the user does not have permission to access it; a field in an object will not be returned if the user has permission to access the object, but not that individual field.

  • Full Object - this representation includes all available information about a given resource. This representation is returned as part of a request that asks for a specific object of that resource’s type. For instance, the full object representation of a user would be returned by a request to /users/12.json

  • Partial Object - this representation is a strict subset of the full object representation of a given resource. This representation is returned from requests to a collection of objects (eg, /users.json), or when an object is returned contained inside another object. For example, a Kudos object contains a user object in its poster property. When the full object representation of a kudos is fetched, it includes a partial object representation of the poster as part of the kudos object.

There is only one root object in each response. This object may be an array containing other objects, or it may be a single object that may contain sub-objects. But if multiple objects are returned from a single request, they are always nested inside something else.

Users and Accounts

Every company that is signed up with TribeHR has their own URL: https://[subdomain].mytribehr.com, where subdomain is a name that the company used to sign up with TribeHR. For instance, My Company, Inc. might use the subdomain mycompany.

Each company is represented by a single account; every account has one or more users, which represent the employees of that company.

Known Issues

  • Some URLs returned in API responses point to API endpoints which are not implemented.