Home

Eugene edited this page Nov 30, 2016 · 250 revisions
Clone this wiki locally

Google Support Group

https://groups.google.com/forum/#!forum/sherpadesk-api

Service URL Endpoint

https://api.sherpadesk.com/

API URL Structure

Many Objects
GET https://{orgKey}-{instanceKey}:{APIToken}@api.sherpadesk.com/{objects}?filterParam=x

Single Object
GET https://{orgKey}-{instanceKey}:{APIToken}@api.sherpadesk.com/{object}/{ID}?filterParam=x

API Calls Meta Data

http://api.sherpadesk.com/metadata

Definitions

Organization - SherpaDesk accounts are organized by Organization/Instance. 99% of the time you only have one organization and one instance.

Instances - 99% of SherpaDesk clients should only have 1 Org and 1 Instance. By default this instance is named "Main". If for some reason you are a larger organization you might have multiple instances like: HR, Accounting,IT, ....

Authenticate

Basic Authentification

Pass your email address and password to retrieve your api token. This is the same api token you can view in the web app by navigating to "Your Profile."

GET https://api.sherpadesk.com/login 
Base64Encode: email:password

headers :
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Response Status: 200 OK

{
    "api_token" : "teo957f8gmae0snzzzce5ma0i1cgax6j",
}

Login with Google ID

It's possible to use Google OpenId 2.0 schema. To get out API token you need to do request

POST api.sherpadesk.com/api/auth/googleopenid

Response Status: 200 OK

{
    "Location" : "m.sherpadesk.com?t=teo957f8gmae0snzzzce5ma0i1cgax6j",
}

Retrieve Orgs and Instances

Use HTTP Basic Authentication in the format = x:api_token Request

GET /organizations/

e.g. https://x:{api_token}@api.sherpadesk.com/organizations/

Response

[
    {
        "key" : "fr2fop",
        "name" : "bigWebApps",
        "instances" : [
            {
                "key" : "f2fs33",
                "name" : "Main Default Instance 1"
            }
        ]
     }
 ]

Create Organization

Request

POST /organizations/

e.g. https://api.sherpadesk.com/organizations/

Parameters:

name - should be 3 or more chars

email

url - should be between 3 and 20 chars

firstname

lastname

password - Password must be alphanumeric with at least 5 characters

password_confirm

how - how did you hear about us, Goggle etc.

is_force_registration -  if is_force_registration = false, then if email already exists in system, you'll get message "email already registered" so you need to give a choice for user, if he wants to login or create new org, like we have on https://app.sherpadesk.com/mc/signuporg.aspx page. If is_force_registration = true, even if email already exists in system, you'll register new organization.

is_force_redirect - automatically redirects after signup (used in widget - http://m.sherpadesk.com/widget.html)

Errors on Org Creation

403 - "Url already exists." if url is reserved

409 - "User already have one registered organization. Please login OR set is_force_registration=true to continue." - if organization already exists

GET PUT POST DELETE Operations

GET 1 Object

GET /tickets/26f23g 
GET /tickets/1001   
GET /accounts/j738d3

GET Many Objects

GET /tickets?status=open
GET /tickets?status=open&status=closed     {status open or closed}
GET /accounts?name=Acme&status=active      {name is Acme AND status is active}
GET /tickets?magic=xxxxx                   {magic command xxxxx, more in the docs on this}

POST Create New Object

POST /tickets
POST /accounts

PUT Update Existing Object

PUT /tickets/1001
PUT /tickets/27fh2d
PUT /invoices/h263f2

PUT Special Action

Special Actions like Merging a Ticket or Sending an Invoice to a customer.

PUT /invoices/h263f2   { "action" : "sendEmail" }
PUT /tickets/23f2s3     { "action" : "merge" , "TicketInto" : "72f23f" }

DELETE Delete ONE Object

DELETE /tickets/1001
DELETE /accounts/fhwfe2

All Other Follow-Up Requests

Use HTTP Basic Authentication in the format = org_key-instance_key:api_token

Example Request

https://{org_key}-{instance_key}:{api_token}@api.sherpadesk.com/tickets?status=closed&priority=3

https://2f2h32-2fhwe3:237fh2ifh2i37fh2i3hi2i3rhi273h@api.sherpadesk.com/tickets?status=closed

JQUERY Examples

We use real test user data. So those scripts really work on production.

GET

 // Get ticket info in browser to check
 //  http://441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu@api.sherpadesk.com/tickets/bjna5t        

 $.ajax({
    type: 'GET',
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Authorization', 
                             'Basic ' + btoa('441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu'));
        },
    url: 'http://api.sherpadesk.com' + '/tickets/bjna5t',
    data: {}, 
    dataType: 'json',
    success: function (d) {
             alert('Success! Got ticket ' + d.subject);  
    },
    error: function (e, textStatus, errorThrown) {
             alert(textStatus);
    }
 });

POST

 // Get ticket info in browser to check
 // http://441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu@api.sherpadesk.com/tickets/bjna5t        

 $.ajax({
    type: 'POST',
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Authorization', 
                             'Basic ' + btoa('441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu'));
        },
    url: 'http://api.sherpadesk.com' + '/tickets/bjna5t',
    data: {"note_text" : "test post at " + new Date().toString() }, 
    dataType: 'json',
    success: function (d) {
             alert('Success! Posted response to ticket with key bjna5t');  
    },
    error: function (e, textStatus, errorThrown) {
             alert(textStatus);
    }
 });      

PUT

 // Get ticket info in browser to check
 // http://441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu@api.sherpadesk.com/tickets/bjna5t        

 $.ajax({
    type: 'PUT',
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Authorization', 
                             'Basic ' + btoa('441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu'));
        },
    url: 'http://api.sherpadesk.com' + '/tickets/bjna5t',
    data: {"note_text" : "status changed to CLOSED at " + new Date().toString(),
                    "status" : "closed" }, 
    dataType: 'json',
    success: function (d) {
             alert('Success! Closed ticket with key bjna5t');  
    },
    error: function (e, textStatus, errorThrown) {
             alert(textStatus);
    }
 });         

DELETE

 // First - Get List of Todos
 // http://441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu@api.sherpadesk.com/tickets/bjna5t/todos

 $.ajax({
    type: 'DELETE',
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Authorization', 
                             'Basic ' + btoa('441n5v-xa006j:zse3bjck6cmsfiwb3x5abz7b6dnoojmu'));
        },
    url: 'http://api.sherpadesk.com' + '/todos/baae8841c60f4b3dbffa33053c90aced',
    data: {}, 
    dataType: 'json',
    success: function (d) {
             alert('Success! Todo baae8841c60f4b3dbffa33053c90aced deleted');  
    },
    error: function (e, textStatus, errorThrown) {
             alert(textStatus);
    }
 });  

Response formats

You can get data in those formats:

  • json (default)
  • xml
  • csv
  • jsv

Example call:

 https://api.sherpadesk.com/tickets?format=xml

JSONP CallBacks

Callbacks are needed for users implementing JSONP. Using the “callback” parameter you are instructing our web service end point to wrap the json output in a javascript function. Remember JSONP only supports HTTP GET requests.

?callback=FUNC_NAME

e.g. 
https://api.sherpadesk.com/tickets/1?callback=HelloWorld

a standard JSON Response

{"symbol" : "IBM", "price" : 91.42}

a JSONP Response with CallBack

HelloWorld({"symbol" : "IBM", "price" : 91.42})

Request Limits

API requests are limited to 600 requests per hour. Currently this limit is not being enforced. Be aware in the future it could be enforced.

Pseudo Unique Values | Key

Pseudo Unique Keys are used on some objects and resources in place of integer or guid values. Pseudo Unique values are 6 character strings consisting of random alpha numeric values 0-9 and lower case letters a-z (excluding “o”). e.g. jkl2dz , 23jrea or ticket number There are 35 character combinations.

{
    "key" : "2f234h"
}

Pages

API requests which return multiple objects are limited to 25 records per page. Page numbers start at 0. If your results contain 25 objects you should inspect the next page for additional objects. Use the query string “page=1″.

/tickets/?page=1     {default returns up to 25 records}

/tickets/?page=1&limit=50

Sorting

API requests usually return objects sorted by Date in Descending order. You can choose other options. Use the query string parameters “sort_by=key″ and "sort_order=asc" or "sort_order=desc". You can use any existing parameter name, like "name", "date", "number".

/tickets?sort_by=tech&sort_order=asc        {result with ticket list sorted by tech lastname in ascending order}

Error Messages

Details of error or missing data can be found in Status Description.

HTTP/1.1 400 Missing the user or class to transfer the ticket.
Content-Type: application/json
Content-Length: xxxx

HTML Return Codes

General Codes

1xx – Informational: Request received, continuing process.

2xx – Success: Action successfully received, understood, and accepted.

3xx – Redirection: Client must take additional action to complete the request.

4xx – Client Error: Request contains bad syntax or cannot be fulfilled

5xx – Server Error: Server failed to fulfill an apparently valid request.

Specific Codes

200 OK. Represents a successful transaction

201 Created & Location. Used during POST operation to represent a successful transaction and return the absolute URI of the new resource in the HTTP Location header.

204 No Content. Request was valid, no content is returned. Empty search results.

400 Bad Request. The request was invalid. An accompanying error message will explain the reason.

401 Unauthorized. Authentication were missing or incorrect.

403 Forbidden. The request was understood, but it has been refused. An accompanying error message will explain the reason.

404 Not Found. The URI requested is invalid or the resource requested does not exist

405 Method Not Allowed. The HTTP Method is not allowed on the resource. For example, if you attempt to post to URL which does not support POST.

420 Rate Limit. Your api key is being rate limited.

500 Internal Server Error. Something is broken. Please post to the forum for investigation.

502 Bad Gateway. Service is in a known down state or being upgraded.

Developer Key

App Keys are free and easy to obtain. Currently email support@bigwebapps.com to obtain an app key, include: developer name, email, company name, company website, phone, company email. The App Key uses the same 6 character system we use for Pseudo Unique values. e.g. hsy2sd2

HTTP Verbs

GET

Safe, Idempotent implied.

POST

Non Idempotent, multiple requests can generate duplicate objects. The ID (int/guid) is generated by the server. The location of the object is returned as part of the response. Most similar to CRUD – CREATE statement.

PUT

Idempotent, multiple identical requests should have the same effect. The ID (int/guid) is generated client side and specified in the data transferred to the server. The resource is placed in its final position during the PUT request. Most similar to CRUD – UPDATE statement. If the object exists, replace the entire object with the uploaded data.

DELETE

Idempotent, multiple identical requests should have the same effect.

Field Naming & Formats

Bit – Boolean

Field names can have present or past tense and have the prefix “is_“. e.g. is_active, is_enabled, is_created

Values are 1 (true), 0 (false), “null” (null)

Dates | no time

Format is YYYY-MM-DD

Date fields are in past tense and have the suffix “_date”. e.g. created_date, updated_date, sent_date.

Time

Format is YYYY-MM-DD hh:mm:ss.sTZD (refer to W3C ISO 8601)

Time fields are in the past tense and have the suffix “_time”. e.g created_time, updated_time, sent_time

Examples below are the same date and time.

1994-11-05 08:15:30-05:00

1994-11-05 13:15:30Z

Local Time

Important to know, that api return dates in UTC

So if you need to know instance local time you should get also timezoneoffset from /config

User Foreign Key References

Have the suffix “_userid” or "_userkey" to let developer know this is a USER foreign key

e.g. user_userid, tech_userid, created_userid.

or, if using a Pseudo Key, will have the suffix "_userkey"

e.g. user_userkey, tech_userkey, created_userkey

Objects

/accounts
/classes    
/config  (need to retrieve current instance time_zone_offset, is_location_tracking etc)        
/articles    (kb articles)
/activity (last 25 activities in department)
/projects
/todos
/invoices
/posts
/levels
/organizations
/login
/ping  - a simple method you can call that will return a "All OK!" as long as everything is good. 
/priorities
/queues
/task_types - all available tasktypes 
/tickets
/ticket_actions
/technicians
/time
/files
/locations
/users  (search by email or name)
/payments    (aka staff payments or bills)
/assets    (future)
/travel_logs
/payments

Config

Get a organization Config

/config  

is_onhold_status =false is_time_tracking=true is_freshbooks=false freshbooks_url=https://micajah3.freshbooks.com` is_parts_tracking=false is_project_tracking=true is_unassigned_queue=true is_location_tracking=true is_waiting_on_response=true is_invoice=true is_payments=true is_expenses=true is_class_tracking=true is_travel_costs=true is_priorities_general=true is_confirmation_tracking=true is_ticket_levels=true is_account_manager=true is_require_ticket_initial_post=false is_ticket_require_closure_note=true is_asset_tracking=true timezone_offset=-5 timezone_name=Eastern Standard Time currency=$ businessday_length=540

assets { unique 1_caption, unique 2_caption, unique 3_caption, unique 4_caption, unique 5_caption, unique 6_caption, unique 7_caption }

user { login_id = 4f843b46db68g6879ja9a9841bd2c316 user_id=3 email=jon@me.com firstname=Jon lastname=Key is_techoradmin=true is_useworkdaystimer=true }

Tickets

Get a List of Tickets

/tickets   {returns a default list of tickets}

/tickets?page=2    {returns page 2 of list of tickets, 25 records per page}

/tickets?status=closed&role=user   {filters the list for the property "status" is closed}

/tickets?start_date=2013-12-23&end_date=2013-12-24

/tickets?search=test* {search by word **test** asterix (*) is needed to search parts of words (testing, etc)}

Get Multiple Tickets

/tickets/{key},{key},{key}   {returns full ticket details for chosen ticket keys}

NOTE:

Save both of the number of calls you are making to API as well as the time it takes to build the report you need to compile.

Filtering of Tickets

You allowed to filter by:

  • status

    /tickets?status=open {returns all open tickets related to user -> from api_key}

  • role

    /tickets?role=user {returns all open tickets where I am the user}

  • account

    /tickets?account=xxx {shows tickets with account containing name or id of account}

  • class

    /tickets?class=xxx {shows tickets with class containing name or id of class}

  • location

    /tickets?location=xxx {shows tickets with location containing name or id of location}

List of Statuses

open  
closed
on_hold
    waiting
    new_messages

i.e. 
/tickets?status=open     {returns all open tickets related to user -> from api_key}
/tickets?status=open,closed    {returns all open OR closed tickets}

All Open Tickets

/tickets?query=all&status=allopen         {magic query, shows all open, all users, all techs, everyone}

Waiting Tickets

/tickets?status=waiting         {shows all waiting tickets}

post waiting ticket:

POST /tickets/h8s2f2

{
    "note_text": "example",
    "is_waiting_on_post": true
}

List of Roles Modes

user
tech
alt_tech

i.e. 
/tickets?status=open&user={key}&role=user        {returns all open tickets for user with {key} (or logged user) where he is the user}
/tickets?status=open&user={key}&role=user,tech      {returns all open tickets for user with {key} (or logged user) where he is the user OR tech}
/tickets?status=open&user={key}     {all roles, returns all open tickets for user with {key} (or logged user) where he is the user OR tech OR alt_tech}

Ticket Counts

GET /tickets/counts

returns total count of tickets by statuses:

{
  "new_messages":1,
  "open_all":4,
  "open_as_user":5,
  "open_as_tech":5,
  "open_as_alttech":5
  "onhold":1,
  "reminder":2,
  "parts_on_order":0,
  "unconfirmed":0,
  "waiting":2
}

GET /tickets/counts?status=new_messages {returns only count of tickets with specific status}

GET /tickets/counts/{status} (deprecated, but still supported, will be removed next update)

deprecated, but still supported statuses:

"new"

"open"

"total"

Create a Ticket

POST /tickets

{
    "status" : "open",
    "subject" : "My Printer is Not Working",
    "initial_post" : "user long message here", 
    "class_id" : 3,
    "account_id" : 654321,
    "location_id" : 0,
    "user_id" : 67890,
    "tech_id" : 12345
}

Get a Ticket

GET /tickets/h8s2f2   {returns a single ticket}
GET /tickets/12345   {returns a single ticket}

Update a Ticket

PUT /tickets/h8s2f2/

{
    "status" : "closed",
    "note_text" : "some note"
    "level_id" : 3,
    "project_id": 66,
    "class_id" : 3
    "priority_id" : 3
    "account_id" : 3,
    "account_location_id" : 0,
    "is_transfer_user_to_account": "false",
    "is_waiting_on_response" : "true"
}

Post Response to a Ticket

POST /tickets/h8s2f2/posts (deprecated, but still supported, will be removed next update)

POST /tickets/h8s2f2

{
    "note_text": "example",
    "action": "response"
}

POST /posts

{
    "ticket": "h8s2f2"
    "note_text": "example"
}

Place a Ticket OnHold

PUT /tickets/h8s2f2/

{
    "status" : "onhold",
    "note_text": "example"
}

Close a Ticket

PUT /tickets/h8s2f2/

{
    "status" : "closed",
    "note_text": "example",
    "is_send_notifications": true,
    "resolved": true,
    "confirmed": true,
    "confirm_note": "confirmed by me"
}

ReOpen a Ticket

PUT /tickets/h8s2f2/

{
    "status" : "open",
    "note_text": "example"
}

PickUp a Ticket

PUT /tickets/h8s2f2/

{
    "action" : "pickup",
    "note_text": "example"
}

Confirm a Ticket

PUT /tickets/h8s2f2/

{
    "action" : "confirm",
    "note_text": "example"
}

Transfer To Tech a Ticket

PUT /tickets/h8s2f2/technicians/{tech_id} (deprecated, but still supported, will be removed next update)

PUT /tickets/{key}

{
    "action": "transfer",
    "note_text": "example",
    "tech_id": "111",
    "keep_attached": false
}

"keep_attached" means, keep the current technician attached plus add the new tech.

Attach Alt_User a Ticket

POST /tickets/h8s2f2/users/{user_id} (deprecated, but still supported, will be removed next update)

POST /tickets/{key}

{
    "action": "add_user",
    "user_id": "111"
}

Attach Alt_Tech a Ticket

POST /tickets/h8s2f2/technicians/{tech_id} (deprecated, but still supported, will be removed next update)

POST /tickets/{key}

{
    "action": "add_tech",
    "tech_id": "111"
}    

Classes

Get classes

GET /classes  - returns all classes.

GET /classes?user=1123 - returns all classes for user with id 1123

GET /classes?class_id=123 - returns child classes for class with id 123

Get parent classes of class

GET /classes/parent/123 - return parent classes of class with id=123

Accounts

Get a List of Accounts

GET /accounts  {return list of accounts}

Get an Account

GET /accounts/{account_id}  {return account info, including contact info, logo, list of files, locations, users, projects, assets, statistic (ticket counts, expenses, etc), custom fields)

Example of account statistics info:

account_statistics : { "ticket_counts":{"open":124,"closed":39,"scheduled":2,"followups":4},

"timelogs":44,

"invoices":9,

"hours":23.5392,

"expenses":39380.7100 }

Todos

Get single todo

GET /todos/{id}  

Get a List of Todos

GET /todos {return all todos}

Get a Project and Ticket todos

GET /projects/{id}/todos {return todos of project} (deprecated, but still supported, will be removed next update)

GET /tickets/{key}/todos {return todos of ticket} (deprecated, but still supported, will be removed next update)

GET /todos?ticket=456 {get ticket todos}

GET /todos?project=555 {get project todos}

Input Todo

POST /todos

{
    "title": "example",
    "text": "example",
    "list_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "assigned_id": 458,
    "estimated_remain": 4.8,
    "due_date": "2015-03-31",
    "notify": true
}

Update Todo

POST /todos

{
    "task_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "title": "example",
    "text": "example",
    "assigned_id": 458,
    "estimated_remain": 4.8,
    "due_date": "2015-03-31",
    "notify": true,
    "time_hours": 4.5,
    "time_is_billable": true,
    "time_task_type_id": 4
}

Delete Todo

DELETE /todos/{id} {delete todo}

Complete / UnComplete Todo

PUT /todos/{id}

{
    "is_completed": true
}

Input Todo List a Ticket

POST /todos/list

{
    "ticket_key": "h8s2f2",
    "name": "example",
    "template_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B"
}

Input Todo List to Project

POST /todos/list

{
    "project_id": 458,
    "name": "example",
    "template_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B"
}

Update Todo List

POST /todos/list

{
    "list_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "name": "example"
}

Delete Todo List

DELETE /todos/list/{id} {delete todo list}

Files

Get a List of Files

GET /files/ticket=5fg67g {return ticket files list}

GET /files/{ticket_key} (deprecated, but still supported, will be removed next update)

Get a File

GET /files/{file_id}  {return files itself}

parameter: is_link_only - return only info about file

Post file to ticket

POST /files

{"ticket" : ticket_key, 

"post_id" : "123" }    - (arbitrary) post id (from ticket post list) where files will be added (can be any post including initial post)

NOTE:

You can use most common and reliable multipart/form-data on posting files

SAMPLE PAGE

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<form action="https://api.sherpadesk.com/files/m4hqne" method="POST" enctype="multipart/form-data">
<label><b>Upload Image</b></label>
<div><input type="file" name="img" id="img" /> <button type="submit">Upload</button></div>
</form>
</html>

Users

Get a List of Users

GET /users       {return users list}

GET /users?firstname=Jon&lastname=Vickers&email=jon.vickers@micajah.com  {returns user with Firstname=Jon and Lastname=Vickers and Email=jon.vickers@micajah.com }

GET /users?search=Jon  {returns user with any Firstname=*Jon* or Lastname=*Jon* or Email=*jon* }

GET /users?id=1225  {return user with ID=1225}

Add new (invite) User

POST /users   

parameters:
  • lastname

  • firstname

  • email

  • account (int) - usually current ticket account

  • location (int) - default location, mandatory if location tracking enabled

all parameters mandatory.

Projects

Get Projects

GET /projects

GET /projects?account=123 -  get projects of account 123

GET /projects?tech=123 - get tech 123 projects

Locations

Get Locations

GET /locations

GET /locations?account=123 -  get Locations of account 123

GET /locations?parent_id=1024 - get child Locations for Location with id=1024

GET /locations?name=Atlanta - get Locations with name Atlanta

GET /locations?is_active=false - get inactive Locations

Get a Location

GET /locations/{location_id}

Invoices

Get Invoices

GET /invoices

GET /invoices?account=123 - get invoices of account_id =  123 

GET /invoices?project=123 - get invoices of project_id =  123

GET /invoices?start_date=2013-10-07&end_date=2013-11-07 - get invoices with date range from 2013-10-07 to 2013-11-07 (by default 30 days ago)

Get an Invoice

GET /invoices/{id} where {id} can be a number(3) or key (t6i0p3)

Get an Unbilled Projects and Tickets

GET /invoices?status=unbilled

Create new invoice

POST /invoices?status=unbilled&project=0&account=6&start_date=2013-10-07&end_date=2013-11-07

!Important: start_date and end_date can be correctly seen from list of call GET /invoices?status=unbilled

Invoice adjustments

You allowed to add or exclude timelogs, and other expenses from invoice.

Add recipients

POST /invoices?status=unbilled&project=0&account=6&recipients=tom@me.com,larry@tt.net 

Review and exclude timelogs and other from invoice

GET /invoices/unbilled?project=0&account=-1&time_logs=1081,1053&expenses=94bf0d06-547c-4024-bffb-5ec49051c925

Available parameters to exclude:

  • expenses
  • time_logs
  • adjustments_note
  • adjustments
  • retainers
  • travel_logs

Commit excluded timelogs and other to invoice

POST/invoices/unbilled?project=0&account=-1&time_logs=1081,1053&expenses=94bf0d06-547c-4024-bffb-5ec49051c925

Send an Invoice to a customer.

PUT /invoices/h263f2   
{ 
   "action" : "sendEmail"
   "recipients" : "tom@me.com,larry@tt.net" 
}

Task Types

Get Task Types

GET /task_types - get all task types

GET /task_types?project=123 - get project 123 task types

GET /task_types?ticket=456  - get ticket task types

GET /task_types?account=123  - get account task types

GET /task_types?tech=456  - get technician task types

Get single Task Type

GET /task_types/{key}  

Activity

Get activity of department

GET /activity

Get activity of user

GET /activity?user=33

GET /activity/{user_id} (deprecated, but still supported, will be removed next update)

Time

Additional parameters:

start_date - filters time logs begin from start_date

end_date - filters time logs end from end_date

Get Time Logs of Ticket

GET /time?ticket=gfher5

Get Time Logs of Project

GET /time?project=123

Get Time Logs of Project Tickets

GET /time?project=123&type=tickets

Get Recent Time Logs

type:
* recent - {returns all recent time logs}
* unlinked_fb - {returns all recent unlinked FreshBooks time logs}
* unlinked_fb_billable - {returns all recent unlinked FreshBooks and Billable time logs}
* linked_fb - {returns all recent linked FreshBooks time logs}
* invoiced - {returns all recent invoiced time Logs}
* not_invoiced - {returns all recent not invoiced time Logs}
* not_invoiced_billable - {returns all recent not invoiced and Billable time Logs}
* not_invoiced_nonbillable - {returns all recent not invoiced and Non Billable time Logs}
* unlinked_qb - {returns all recent unlinked QuickBooks time logs}
* unlinked_qb_billable - {returns all recent unlinked QuickBooks and Billable time logs}
* linked_qb - {returns all recent linked QuickBooks time logs}
* hidden_from_invoice - {returns all recent hidden from invoice time logs}

project - {project id}

account - {account id}

tech - {technician id}

i.e.
GET /time?type=recent&project=123&account=354&tech=465

Get single Time Log Entry

GET /time?ticket_time_id=23 {return a ticket time log record}
GET /time?project_time_id=678 {return a project time log record}

GET /time/123?type=ticket (deprecated, but still supported, will be removed next update)

GET /time/123?type=project (deprecated, but still supported, will be removed next update)

Input Time a Ticket

POST /time

{
    "ticket_key": "h8s2f2",
    "note_text": "example",
    "task_type_id": 2,
    "hours": 2,
    "is_billable": true,
    "date": "2014-03-31",
    "start_date": "2014-03-31 11:14:20:00",
    "stop_date": "2014-03-31 13:14:20:00",
    "tech_id": 27,
    "is_billable": true,
    "complete" : "20", //percent
    "remain_hours": 3,
    "prepaid_pack_id": 4
}

Input Time to Project or Account

POST /time

{
    "tech_id" : 543,
    "project_id": "3421",
    "account_id" :"-1",
    "note_text": "example",
    "task_type_id": 2,
    "hours": 2.5,
    "is_billable": true,
    "date": "2014-03-31",
    "start_date": "2014-03-31 11:14:20:00",
    "stop_date": "2014-03-31 13:14:20:00",
    "is_billable": true,
    "complete" : "20", //percent
    "remain_hours": 3,
    "prepaid_pack_id": 4
}

Update Time a Ticket

PUT /time/{key}

{
    "note_text": "example",
    "task_type_id": 2,
    "hours": 2,
    "is_billable": true,
    "date": "2014-03-31",
    "start_date": "2014-03-31 11:14:20:00",
    "stop_date": "2014-03-31 13:14:20:00",
    "tech_id": 27,
    "is_billable": true,
    "complete" : "20", //percent
    "remain_hours": 3,
    "prepaid_pack_id": 4
}

Update Time to Project or Account

PUT /time/{key}

{
    "is_project_log": true,
    "tech_id" : 543,
    "project_id": "3421",
    "account_id" :"-1",
    "note_text": "example",
    "task_type_id": 2,
    "hours": 2.5,
    "is_billable": true,
    "date": "2014-03-31",
    "start_date": "2014-03-31 11:14:20:00",
    "stop_date": "2014-03-31 13:14:20:00",
    "prepaid_pack_id": 4
}

POST /project_time (removed)

Time Entry as Billable / Non Billable

PUT /time/{key}

{
"is_billable" : true,
"is_project_log": true
}

PUT /time/billable/{key} (deprecated, but still supported, will be removed next update)

PUT /time/nonbillable/{key} (deprecated, but still supported, will be removed next update)

{
    "is_project_log": true
}

Hide / Unhide Time Entry from Invoice

PUT /time/{key}

{
"hidden_from_invoice" : true,
"is_project_log": true
}

Delete Time

DELETE /time/{key}

{
    "is_project_log": true
}

Travel Logs

Add Travel Log to ticket

POST /travel_logs

{
    "ticket_key": "h8s2f2",
    "start_location": "New York",
    "end_location": "Moscow",
    "distance": 2000,
    "rate": "2.5",
    "date": "2014-03-31",
    "note": "my travel",
    "is_technician_payment": true
}

Add Travel Log to Account

POST /travel_logs

{
    "account": "111",
    "start_location": "New York",
    "end_location": "Moscow",
    "distance": 2000,
    "rate": "2.5",
    "date": "2014-03-31",
    "note": "my travel",
    "is_technician_payment": true
}

Hide / Unhide Travel Log from Invoice

PUT /travel_logs/{key}

{
"hidden_from_invoice" : true
}

Delete Travel Log

DELETE /travel_logs/123

Expenses

Get Recent Expenses

type:
* recent - {returns all recent expenses}
* unlinked_fb - {returns all recent unlinked FreshBooks expenses}
* unlinked_fb_billable - {returns all recent unlinked FreshBooks and Billable expenses}
* linked_fb - {returns all recent linked FreshBooks expenses}
* invoiced - {returns all recent invoiced expenses}
* not_invoiced - {returns all recent not invoiced expenses}
* not_invoiced_billable - {returns all recent not invoiced and Billable expenses}
* not_invoiced_nonbillable - {returns all recent not invoiced and Non Billable expenses}
* unlinked_qb - {returns all recent unlinked QuickBooks expenses}
* unlinked_qb_billable - {returns all recent unlinked QuickBooks and Billable expenses}
* linked_qb - {returns all recent linked QuickBooks expenses}
* hidden_from_invoice - {returns all recent hidden from invoice expenses}

project - {project id}

account - {account id}

tech - {technician id}

i.e.
GET /expenses?type=recent&project=123&account=354&tech=465

Get single Expense

GET /expenses/{key}  

Expense as Billable / Non Billable

PUT /expenses/{key}

{
"is_billable" : true
}

Hide / Unhide Expense from Invoice

PUT /expenses/{key}

{
"hidden_from_invoice" : true
}

Get single Expense Category

GET /expenses/categories/{key} 

Input Expense a Ticket

POST /expenses

{
    "ticket_key": "h8s2f2",
    "tech_id": 27,
    "note": "example",
    "note_internal": "example",
    "amount": 2,
    "is_billable": true,
    "category_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "vendor": "vendor name",
    "markup": 10,
    "date": "2014-03-31",
    "is_technician_payment": true
}

Input Expense to Project or Account

POST /expenses

{
    "account_id": 125,
    "project_id": 458,
    "tech_id": 27,
    "note": "example",
    "note_internal": "example",
    "amount": 2,
    "is_billable": true,
    "category_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "vendor": "vendor name",
    "markup": 10,
    "date": "2014-03-31",
    "is_technician_payment": true
}

Update Expense a Ticket

POST /expenses

{
    "expense_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "ticket_key": "h8s2f2",
    "tech_id": 27,
    "note": "example",
    "note_internal": "example",
    "amount": 2,
    "is_billable": true,
    "category_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "vendor": "vendor name",
    "markup": 10,
    "date": "2014-03-31",
    "is_technician_payment": true
}

Update Expense to Project or Account

POST /expenses

{
    "expense_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "account_id": 125,
    "project_id": 458,
    "tech_id": 27,
    "note": "example",
    "note_internal": "example",
    "amount": 2,
    "is_billable": true,
    "category_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B",
    "vendor": "vendor name",
    "markup": 10,
    "date": "2014-03-31",
    "is_technician_payment": true
}

Delete Expense

DELETE /expenses/{key}

Payments

Get an Payment

GET /payments/{id} where {id} can be a number(3)

PrePaid Packs

Get an PrePaid Packs

GET /prepaid_packs/{id} where {id} can be a number(3)

FreshBooks

Get FreshBooks Clients

GET /freshbooks/clients

Create FreshBooks Client from SherpaDesk Account

POST /freshbooks/clients

{
    "account_id": 123
}

Unlink FreshBooks Client

DELETE /freshbooks/clients/{key}

{
    "is_unlink": true
}

Delete FreshBooks Client

DELETE /freshbooks/clients/{key}

Get FreshBooks Staff

GET /freshbooks/staff

Unlink FreshBooks Staff

DELETE /freshbooks/staff/{key}

Get FreshBooks Projects

GET /freshbooks/projects/?client=123&staff=321

Create FreshBooks Project from SherpaDesk Project

POST /freshbooks/projects

{
    "project_id": 123,
    "fb_client_id": 12,
    "fb_staff_id": 2,
    "account_id": 123
}

Unlink FreshBooks Project

DELETE /freshbooks/projects/{key}

{
    "is_unlink": true
}

Delete FreshBooks Project

DELETE /freshbooks/projects/{key}

Get FreshBooks Tasks

GET /freshbooks/tasks/?project=123

Create FreshBooks Task from SherpaDesk Task Type

POST /freshbooks/tasks

{
    "task_type_id": 123,
    "fb_project_id": 12
}

Find FreshBooks Task

GET /freshbooks/tasks?name=general

Unlink FreshBooks Task

DELETE /freshbooks/tasks/{key}

{
    "is_unlink": true
}

Delete FreshBooks Task

DELETE /freshbooks/tasks/{key}

Input FreshBooks Time Entry

POST /freshbooks/time

{
    "fb_staff_id": 123,
    "fb_project_id": 321,
    "fb_task_type_id": 2,
    "hours": 2,
    "notes": "example",
    "date": "2014-03-31",
    "time_id": 123,
    "is_project_log": true
}

Update FreshBooks Time Entry

PUT /freshbooks/time/{key}

{
    "fb_staff_id": 123,
    "fb_project_id": 321,
    "fb_task_type_id": 2,
    "hours": 2,
    "notes": "example",
    "date": "2014-03-31"
}

Unlink FreshBooks Time Entry

DELETE /freshbooks/time{key}

{
    "is_unlink": true,
    "is_project_log": true
}

Delete FreshBooks Time Entry

DELETE /freshbooks/time/{key}

{
    "is_project_log": true
}

Input FreshBooks Expense

POST /freshbooks/expense

{
    "fb_staff_id": 123,
    "fb_category_id": 2,
    "fb_project_id": 321,
    "fb_client_id": 2,
    "amount": 2,
    "vendor": "vendor name",
    "notes": "example",
    "date": "2014-03-31",
    "expense_id": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B"
}

Update FreshBooks Expense

PUT /freshbooks/expense/{key}

{
    "fb_staff_id": 123,
    "fb_category_id": 2,
    "fb_project_id": 321,
    "fb_client_id": 2,
    "amount": 2,
    "vendor": "vendor name",
    "notes": "example",
    "date": "2014-03-31"
}

Unlink FreshBooks Expense

DELETE /freshbooks/expense/del/{key}

{
    "is_unlink": true
}

Delete FreshBooks Expense

DELETE /freshbooks/expense/del/{key}

Get FreshBooks Categories

GET /freshbooks/category/

Input FreshBooks Category

POST /freshbooks/category

{
    "category_id ": "0AC642DE-468A-4B7A-8DB8-0FF3E4353E1B"
}

Unlink FreshBooks Category

DELETE /freshbooks/category/del/{key}

{
    "is_unlink": true
}

Delete FreshBooks Category

DELETE /freshbooks/category/del/{key}

Link FreshBooks Stuff

POST /freshbooks

{
    "user_id": 123,
    "fb_staff_id": 321,
    "account_id": 25,
    "fb_client_id": 12,
    "project_id": 123,
    "fb_project_id": 3,
    "task_type_id": 2,
    "fb_task_type_id": 4,
    "category_id": "17206C73-DC07-46BE-8FA9-42A0E4CDC11A",
    "fb_category_id": 2
}

Links

RESTful API Server – Doing it the right way (Part 1) (http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-1/) Nobody Understands REST or HTTP (http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http)