API & Architecture
Verified against source (19)
Config/CustomRoutes.configConfig/Abstract.configapplication/QboRouteHandler.csapplication/HttpAsyncHandler.csapplication/AbstractObject.csapplication/GenericObject.csapplication/CreateObject.csapplication/Enumerations.csapplication/Schedule.csConfiguration/SqlPattern.csConfiguration/CustomRoute.csConfiguration/DbAttributes.csInterfaces/IQueue.csInterfaces/IService.csInterfaces/IMethodListener.csServices/Recipe.csapplication/HealthCheckHandler.cssrc/objectqueueqbo.Queue.Amazon/SimpleQueue.cs
Every QBO module is a class (Contact, Process, Attachment, Decision, …) that derives from AbstractObject. Its operations are C# methods, SQL statements defined in its configuration, or configured services. All of them are reachable through the same routes.
Routes
Section titled “Routes”| Route | Runs | Example |
|---|---|---|
/api/{module}/{operation} |
Synchronously on the web server | /api/contact/search?LastName=Smith |
/api/{module}/{operation}/{id} |
Synchronously, with ID={id} |
/api/contact/summary/1001 |
/api/{module}/{id} |
GET → Summary, DELETE → Delete, other verbs → Save |
/api/contact/1001 |
/api/{module}/queue/{operation} |
Queued for an app server | /api/attachment/queue/generate?Template=Welcome Letter&Object=Contact&ObjectID=1001 |
/healthcheck |
Returns the installed version |
A parent-scoped form, /api/{Object}/{ObjectID}/{module}/{operation}, is shorthand for passing Object and ObjectID. For example, /api/attachment/search?Object=Process&ObjectID=2002 lists a case’s documents.
Parameters can be sent on the query string or in the body as form-encoded, XML, or JSON. Send sensitive values (SSNs, account numbers) in the body so they stay out of URLs and logs. Authenticate with an X-ApiKey header (see Security).
Output
Section titled “Output”Set Output=Xml|Json|JsonP|Xhtml|Html|Csv, or send an Accept header (application/json, text/xml, text/csv).
Synchronous or queued
Section titled “Synchronous or queued”Use /api/{module}/{operation} for interactive calls. Use /api/{module}/queue/{operation} for long-running work, batches, document generation, third-party calls that need throttling or retries, and anything scheduled. The queued call returns immediately with a confirmation (Output=Xml shown):
<QueueMessageItem> <Queue>DefaultQueue</Queue> <MessageID>…</MessageID></QueueMessageItem>Scheduled messages also include a ScheduleID.
| Parameter | Purpose |
|---|---|
QueueName |
Target queue. Defaults to the queue configured for the operation, then DefaultQueue. |
QueuedDate |
Run at a future time. The message waits in the future queue until then. |
ScheduleName |
Run on a recurring schedule, such as Daily at 6am. QBO re-queues after each run. |
ScheduleLabel |
A unique name for the schedule when the same operation needs different schedules. |
QueueLabel |
A custom label for the queued item (when custom labels are enabled). |
POST /api/organization/queue/listen ?Listeners=Nightly Sync &ScheduleName=Daily at 5:00am &ScheduleLabel=Organization Nightly Sync 5amTest schedule text before using it:
GET /api/schedule/parse?ScheduleName=Monthly on the 2nd Sun every 2 months @ 6am&Output=XmlStandard operations
Section titled “Standard operations”Every module inherits these from AbstractObject and the shared Abstract.config:
| Operation | Purpose |
|---|---|
Save |
Insert or update: with an ID it updates, without one it inserts (applying template rules). |
Search |
Paged search with {Extranet.Default} row-level security applied. |
SmartSearch |
Free-text search across configured search terms. |
Select |
Read one record by ID. |
Summary |
A record plus its significant children (what summary pages render). |
Delete / BulkDelete |
Delete records. |
BulkUpdate |
Update the columns you pass on many records (ID list). |
ListByParent |
Children of a parent record. |
ObjectTree |
All related Object / ID pairs. |
Dashboard / Pivot |
Aggregates by dimension. |
GrantAccess / RevokeAccess |
Manage group access to records. |
Listen |
Run the module’s data listeners (all, or those named in Listeners) for changes since From or the last scheduled run. |
SelectByTemplate |
Find the existing templated record that the template’s repeatability says to reuse. |
Each operation is guarded by a permission named {Module}{Operation}, such as ContactSearch.
Search parameters
Section titled “Search parameters”| Parameter | Purpose |
|---|---|
| any column name | Matches that column, for example LastName=Smith. |
SqlFilters |
Comma-separated named filters from the module’s configuration, for example SqlFilters=Active. |
OrderBy |
Sort column; prefix with - for descending (OrderBy=-CreatedDate). |
DisplaySize / RecordStart |
Paging. |
Save conventions
Section titled “Save conventions”Save behaves like PATCH. Properties you omit are left alone; a property sent with an empty value is set to null.
POST /api/contact/save?ID=1001&FirstName=Jane&MiddleName=&LastName=DoeRelated data saves in the same call:
- Parent record:
{Object}_{Field}, for exampleOrganization_Organization=Acme Lending. Use withObject=Organizationand noObjectIDto create the parent. - Nested collections:
{Object}_{Collection}_{index}_{Field}, for exampleOrganization_Contacts_0_Email=ada@acme.example. - Templates:
TemplateorTemplateIDapplies the template’s defaults and repeatability (see Templates).
Use Output=Xml when you need new IDs back; JSON output omits a record’s data fields.
Extending QBO
Section titled “Extending QBO”| Extension point | What it is |
|---|---|
| Statement | A SQL statement in a module’s configuration. Available as an operation with its own permission, and can use {Extranet.*} for row-level security. |
| Extension method | A C# extension method on a module class, decorated with [DbVoidMethod] (or another DbMethod attribute). |
IService |
A plugin operation. Built-ins include RestApiService (REST calls), SqlService, ImportService, and Recipe (a series of operations with parameter substitution between steps). |
IMethodListener |
Fires when named operations run; QueueListener queues the follow-up instead of running it inline. |
IQueue |
A queue implementation: Amazon SQS, SQL Server Service Broker, and QBO’s own future, failure, and callback queues. |
IFileObject / IGenerator |
Document storage and generation plugins (see Document Management). |
| Custom route | A URL mapped to an operation, with optional Handler (IQboHttpHandler) and ExceptionHandler. |
Configuration is stored as configuration entries (Source, ConfigurationType, ConfigurationKey, ConfigurationXml) and shipped as setup packages (Setup.{Name}.xml), so changes promote between environments as data.
Asynchronous callbacks
Section titled “Asynchronous callbacks”An operation that starts external work, such as ordering a report from a vendor, can be marked [DbVoidMethod(Async = true)]. Workflow and imports then wait for a matching End{Operation} call instead of completing immediately. When the vendor delivers, the delivery operation calls EndInvokeAsync("End{Operation}", …), and the waiting workflow step or import continues.
[DbVoidMethod(Async = true)]public static async Task WidgetOrderAsync(this ContactObject contact, IDictionary<string, object> parameters){ // place the order with the vendor}
[DbVoidMethod(Async = true)]public static async Task WidgetDeliveryAsync(this ContactObject contact, IDictionary<string, object> parameters){ // save the results, then release anything waiting on the order await contact.EndInvokeAsync("EndWidgetOrder", "".ToProperties());}
[DbVoidMethod]public static Task EndWidgetOrderAsync(this ContactObject contact, IDictionary<string, object> parameters) => Task.CompletedTask;