Skip to main content

Legacy API conventions

Applies only to the Legacy APIs

This page documents the conventions of the Legacy APIs, the previous generation of hand-written REST endpoints. They remain fully supported for existing integrations.

If you are building something new, use the Vendasta APIs and the conventions in Getting Started instead. The two sets of conventions are not interchangeable.

The Legacy APIs follow JSON:API: resources are addressed by path, and filtering, paging, and field selection are expressed as query parameters.

Filters

Filtering is expressed as bracketed query parameters, one per filterable attribute:

GET /v1/businessLocations?filter[partner.id]=ABC&filter[searchTerm]=dental

Which filters an endpoint accepts is listed on its page in the reference. Filter names use dotted paths for related resources (filter[partner.id], filter[businessLocation.id]). There is no cross-field boolean grammar; multiple filters combine as AND.

Paging

Paging is query parameters, and the response hands you a ready-made link to the next page.

DirectionFieldMeaning
Requestpage[limit]Maximum items to return. Defaults to 10, capped at 1000
Requestpage[cursor]Opaque cursor. Omit for the first page
Responselinks.nextFull URL for the next page, absent on the last page
Responselinks.first / links.prev / links.lastOther positions, where the endpoint supports them

Follow links.next as given. The URL already carries every query parameter from your original request, filters included, with only the paging parameters swapped. There is nothing to resend.

{
"data": [ /* ... */ ],
"links": {
"self": "/v1/businessLocations?filter[partner.id]=ABC&page[limit]=10",
"next": "/v1/businessLocations?filter[partner.id]=ABC&page[limit]=10&page[cursor]=eyJsYXN0..."
}
}

Call that URL unchanged for the next page. Stop when links.next is absent.

Two caveats: not every list endpoint is paged, and of those that are, some return links.next only without first, prev, or last. Cursors are positional, so records created or deleted between calls can shift the page boundary and cause rows to be skipped or repeated.

Errors

Errors are JSON:API error objects, returned as an array so a single response can report more than one problem:

{
"errors": [
{
"status": "400",
"code": "QueryParameterBadValue",
"title": "Invalid filter value",
"detail": "filter[createdAt] must be an RFC-3339 timestamp.",
"source": { "parameter": "filter[createdAt]" }
}
]
}
FieldMeaning
statusHTTP status code, as a string
codeApplication error code identifying the specific problem
titleShort summary, stable across occurrences
detailExplanation specific to this occurrence
sourceWhich parameter or pointer caused it, where applicable

Read code to branch programmatically. title and detail are for humans.

This is a different shape from the Vendasta APIs, which return a single code, message, and details object. See Errors for that.

Localization

Translated content is available on the Legacy APIs. Provide the languages the user reads with the Accept-Language request header; browsers often set it for you. If it is not set, en-US is used.

We pick the most appropriate locale from the header and the available translations. Resource attributes representing an enum carry both an untranslated {attribute}Code and a translated {attribute}Name. Translatable fields are read only over the API.

Not available on the Vendasta APIs

The Vendasta APIs return enum values as untranslated codes (for example FIELD_TYPE_EMAIL) with no translated companion field, and do not act on Accept-Language.

Sparse fieldsets

You can limit which attributes come back per resource type with fields[<resourceType>]:

GET /v1/businessLocations?fields[businessLocations]=name,address

Supported on a small number of endpoints. Check the endpoint's page in the reference.

What is shared with the Vendasta APIs

  • Authentication. The same OAuth2 bearer token, in the same Authorization header. See Authorization. The scope vocabulary differs: the Legacy APIs use coarse domain scopes (business, order, sales.contact, user.admin), while the Vendasta APIs use finer per-service scopes (crm.contact:read).
  • Dates and times. RFC-3339 in both. See Dates & times.
  • Lifecycle statuses. The x-lifecycle annotations described in Versioning apply to these APIs.