Background
QBO's RESTful API allows developers to leverage QBO functionality without relying on our user interface. Our API can be called from:
Java, ASP.NET or any other server-side language using simple HTTP requests.
Javascript, using standard AJAX request
The QBO javascript library
We'll start with a use case: managing an insurance claim for a customer.
Create a customer.
The QBO Contact table represent names and addresses. Customers are a perfect fit for the Contact table. Thus, we'll create a Contact to represent our customer.
Request:
Contact/Contact.ashx/Save?FirstName=John&LastName=Doe&Address=123%20Main%20Street&City=Anywhere&State=NY&PostalCode=12001&Output=Json
Response:
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
X-Execution-Time: 33
Date: Fri, 06 Feb 2015 19:01:45 GMT
Content-Length: 207
{
"Methods": [],
"Licenses": [],
"ContactID": 49781,
"Contact": "Doe, John",
"FirstName": "John",
"LastName": "Doe",
"Address": "123 Main Street",
"City": "Anywhere",
"State": "NY",
"PostalCode": "12001"
}
Notes:
The request includes Contact.ashx/Save. Generically, this follows a {ClassName}/{Operation} pattern which we'll refer to repeatedly.
In the request, we've included &Output=Json, because we like working with JSON. You could choose &Output=Xml, or JsonP, or Csv if you prefer.
We've use a GET here for brevity; you are welcome to use a POST instead
The response includes a ContactID; this is the primary key of the contact created
From here on out, we'll ignore the top of the HTTP response for brevity
Updated a Customer
Request:
Contact/Contact.ashx/Save?ContactID=49781&Phone=800.555.1212&Email=jdoe@example.com&Output=Json
Response:
{
"Methods": [
{
"ContactMethodID": 25672,
"ContactMethod": "Email",
"ContactID": 49781,
"MethodType": "Email",
"ContactValue": "jdoe@example.com",
"PrimaryMethod": true
},
{
"ContactMethodID": 25671,
"ContactMethod": "Phone",
"ContactID": 49781,
"MethodType": "Phone",
"ContactValue": "800.555.1212",
"PrimaryMethod": true
}
],
"Licenses": [],
"ContactID": 49781
}
Notes:
We just wanted to update the contact with a phone number
Methods represent all methods of communicating with a contact; here we see email and phone listed
Create an Insurance Claim
An insurance claim can be a complicated creature, especially if it winds up being disputed. If we were living in a paper world, we'd probably put each insurance claim in a manilla folder, label the outside with the customer's name and the date the claim was filed, and then stick all related paperwork into said folder. The QBO Process table is a good fit for such a construct.
Request:
Process/Process.ashx/Save?Object=Contact&ObjectID=49781&Process=Insurance%20Claim&DateOpened=2/1/2015&Output=Json
Response:
{
"Delays": [],
"ProcessID": 3396,
"Process": "Insurance Claim",
"DateOpened": "2015-02-01T00:00:00",
"Object": "Contact",
"ObjectID": 49781
}
Notes:
A Process can be bound to any object using the QBO Object/ObjectID pattern.
In this case, we're setting the Process.Object = 'Contact', and Process.ObjectID = 49781 (the primary key for our customer created above).
The primary key for the newly created Process in this example is 3396
View all Information Related to an Insurance Claim
The Select statement will retrieve basic information about an object, while Summary will retrieve an object and is ancestors and descendants.
Select Request:
Process/Process.ashx/Select?ID=3396&Output=Json
Select Response:
{
"Delays": [],
"ProcessID": 3396,
"Process": "Insurance Claim",
"DateOpened": "2015-02-01T00:00:00",
"Object": "Contact",
"ObjectID": 49781
}
Summary Request:
Process/Process.ashx/Summary?ID=3396&Output=Json
Summary Response:
{
"Root": {
"ContactItem": {
"ContactID": "49781",
"Contact": "Doe, John",
"FirstName": "John",
"LastName": "Doe",
"Address": "123 Main Street",
"City": "Anywhere",
"State": "NY",
"PostalCode": "12001",
"CreatedPersonID": "374",
"CreatedDate": "2015-02-06T14:30:24.773",
"UpdatedPersonID": "374",
"UpdatedDate": "2015-02-06T14:30:24.773",
"Phone": "800.555.1212",
"Email": "jdoe@example.com"
},
"ProcessItem": {
"ProcessID": "3396",
"Process": "Insurance Claim",
"DateOpened": "2015-02-01T00:00:00",
"Object": "Contact",
"ObjectID": "49781",
"CreatedPersonID": "374",
"CreatedDate": "2015-02-06T14:45:47.400",
"UpdatedPersonID": "374",
"UpdatedDate": "2015-02-06T14:45:47.400",
"CreatedPerson": "epatrick@quandis.com",
"UpdatedPerson": "epatrick@quandis.com",
"ParentLabel": "Doe, John"
}
}
}
Add a Message
Messages are the yellow stickies on the manila folder that is our process.
Request:
Message/Message.ashx/Save?Process&ObjectID=3396&Subject=Customer is now healthy&BodyText=Doc says they'll be fine&Output=Json
Response:
{
"Object": "Process",
"ObjectID": 3396,
"ActiveRecipients": [],
"BccAddress": "",
"CcAddress": "",
"DateAdded": "/Date(1423493949801-0500)/",
"From": null,
"Message": "Customer is now healthy",
"MessageID": 54358,
"Recipients": [],
"ReplyToAddress": "",
"ToAddress": "",
"BodyText": "Doc says they'll be fine"
}
Send an Email
Sending an email is the same as adding a message, except we call Message/Send instead of Message/Save.
Request:
Message/Message.ashx/Send?Object=Process&ObjectID=3396&ToAddress=jdoe@example.com&Subject=Insurance Claim 3966&BodyHTML=<b>Glad you're better!</b>&Output=Json
Response:
{
"Recipients": [
{
"MessageRecipient": "jdoe@example.com",
"ReadGUID": "00000000-0000-0000-0000-000000000000",
"Category": 0
}
],
"ActiveRecipients": [
{
"MessageRecipient": "jdoe@example.com",
"ReadGUID": "00000000-0000-0000-0000-000000000000",
"Category": 0
}
],
"ToAddress": "jdoe@example.com",
"CcAddress": "",
"BccAddress": "",
"ReplyToAddress": "",
"Message": "Insurance Claim 3966",
"DateAdded": "2015-02-09T10:22:08.9939687-05:00",
"BodyHTML": "<b>Glad you're better!</b>",
"Object": "Process",
"ObjectID": 3396
}
Notes:
You can call Message/SaveEmail to both save and email a message (nice audit trail)
In this example, we used BodyHTML instead of BodyText. Pretty much everyone can read HTML email these days.
Add a Task
Let's schedule a task to verify the insurance claim with the doctor.
Request:
Decision/ImportForm.ashx/Save?Object=Process&ObjectID=3396&ImportForm=Verify Claim&ProjectedCompletion=2/2/2015&Provider=Ira Hurtin&Procedure=Hernia Operation&Phone=800.555.2323
Response:
{
"MaximumDate": "2015-02-16T10:27:20.753",
"ImportFormID": 4497,
"ImportForm": "Verify Claim",
"ProjectedCompletion": "2015-02-02T00:00:00",
"XmlData": {
"ImportFormXml": {
"Provider": "Ira Hurtin",
"Procedure": "Hernia Operation",
"Phone": "800.555.2323"
}
},
"ProjectedOriginal": "2015-02-02T00:00:00",
"Object": "Process",
"ObjectID": 3396
}
Notes:
Our "task" module is called "ImportForm"
Tasks track ad-hoc data in an XmlData field: in this case, Provider, Procedure, and Phone. Create fields on the fly!
Get a List of Pending Tasks
Request
Decision/ImportForm.ashx/Search?ActualCompletion=&Output=Json
Response
{
"ImportFormCollection": {
"ImportFormItem": [
{
"ImportFormID": "4497",
"ImportForm": "Verify Claim",
"ProjectedCompletion": "2/2/2015 12:00:00 AM",
"XmlData": {
"ImportFormXml": {
"Provider": "Ira Hurtin",
"Procedure": "Hernia Operation",
"Phone": "800.555.2323"
}
},
"ProjectedOriginal": "2/2/2015 12:00:00 AM",
"Object": "Process",
"ObjectID": "3396",
"CreatedPersonID": "374",
"CreatedDate": "2/9/2015 10:27:20 AM",
"UpdatedPersonID": "374",
"UpdatedDate": "2/9/2015 12:03:29 PM",
"CreatedPerson": "epatrick@quandis.com",
"UpdatedPerson": "epatrick@quandis.com",
"RecordCount": "1"
}
]
}
}
Notes:
When calling {ClassName}/Search, the JSON returned follows a pattern of {ClassName}Collection.{ClassName}Item
The search parameters are very flexible
// Show just tasks associated with our specific claim
Decision/ImportForm.ashx/Search?ActualCompletion=&Object=Process&ObjectID=3396Output=Json
// Show just 'Verify Claim' tasks
Decision/ImportForm.ashx/Search?ActualCompletion=&ImportForm=Verify Claim&Output=Json
// Show tasks due this week; note the use of a range operation -=
Decision/ImportForm.ashx/Search?ActualCompletion=&ProjectedCompletion-=2/1/2015,2/8/2015&Output=Json
Upload a Document
Request
POST {server}Attachment/Attachment.ashx/UploadChunk?Object=Process&ObjectID=3396&FileName=Sample.txt HTTP/1.1
...
Content-Length: 77
Hello World!
This is a simple text file, but QBO handles binary files too.
Response
{
"name": "Sample.txt",
"size": "77",
"error": 0,
"finish": true,
"upload_name": "8f0ab4f9-7a5f-4113-8b96-b11da79fe8c5",
"AttachmentItem": {
"Object": "Process",
"ObjectID": 3396,
"Attachment": "Sample.txt",
"AttachmentID": 6251,
"Compression": false,
"FileName": "Sample.txt",
"FileObjectAssembly": "Amazon S3",
"Length": 77,
"LengthCompressed": 77,
"PathURL": "/Process/3396/Sample.txt"
}
}
Notes:
The QBO Attachment module handles documents
Attachment/UploadChunk supports, er, chunked upload (nice integration with the HTML5 spec)
The response JSON root contains properties representing the status of a chunk
The response JSON's AttachmentItem.AttachmentID is the unique ID of the recently uploaded document
Download a Document
Contact
Properties:
FirstName
MiddleName
LastName
Address
City
State
PostalCode
Prefix
Suffix
Company
Title
USSSN
BirthDate
DeathDate
Latitude
Longitude
Methods:
Save
Select
Summary
Geocode
Normalize