API Versioning

Outline

LegalServer's Core API is available in three versions: v1, v2, and v3.

All three versions follow the same general REST model, but they differ in how they handle lookups, response size, search behavior, and request-control parameters.

This page is intended as a public-facing overview for API consumers. For endpoint-by-endpoint details, use the published OpenAPI documentation at apidocs.legalserver.org.

Availability

  • API v1 and API v2 are available on all sites.
  • API v3 is available for beta testing upon request.
  • Some create, update, and other advanced operations are part of the Premium APIs and may not be enabled on every site.

At a Glance

Feature V1 V2 V3
Status Stable and supported Active development and supported Beta on request
Default response shape Full object Full object Primary UUID only unless you request more fields
Lookup output Usually simple text Structured lookup object Structured lookup object
Lookup input Usually simple text or UUID, depending on endpoint Flexible: name, ID, or lookup object Flexible: name, ID, or lookup object
Multiselect lookup output Objects with all_values string plus individual_values array Structured array of objects Structured array of objects
Date output Objects with raw_value and text_value ISO date format ISO date format
Metaparameters Traditional parameter names only Supports both traditional names and $-prefixed forms Requires $-prefixed forms
Custom response Not supported Supported (including custom fields on subtables) Supported (including custom fields on subtables)
Search Complexity Identified system fields only Identified system fields and any custom fields Identified system fields and any custom fields
Compound OR search Not supported as a general framework feature Supported on eligible endpoints Supported on eligible endpoints
Search expressions Not supported Not supported as a general framework feature Supported on eligible field types
Upsert support Not supported Supported on endpoints that implement it Supported on endpoints that implement it
Sub-object POST/PATCH support Not supported Not supported Supported on eligible endpoints
Maximum Page Size on Search endpoint Unlimited 100 100
Matter Restrictions Unrestricted Adheres to Office/Program Restrictions and Case level Restrictions/Exclusions Adheres to Office/Program Restrictions and Case level Restrictions/Exclusions
Null Search/Post/Patch %empty% %empty% null to clear a field. @null and @not_nullcan be used as search expressions

Common Concepts

Included vs. Premium APIs

Typically search and read endpoints are included by default. Some create, update, delete, and other more advanced operations are Premium APIs.

Case Note authoring is included. User, Organization, and Contact endpoints are all included.

If a Premium endpoint is not enabled on a site, the API returns 402 Payment Required.

UUIDs

The Core API uses Universally Unique Identifiers (UUIDs) heavily. In all versions, many read and update operations use the UUID in the URL path.

Null Handling

  • In v1 and v2, use %empty% when searching for null values. That same token can also be used in many POST/PATCH operations to clear a scalar field.
  • In v3, use JSON null to clear a field.
  • In v3 searches, eligible fields can also use the @null and @not_null search expressions.

API v1

API v1 is the original Core API version.

What to expect

  • It is stable and still supported.
  • New endpoints may still be added over time.
  • Existing field names and response shapes are intended to remain stable.

Characteristics

  • Lookups are commonly returned as plain text.
  • Responses usually include the full standard field set automatically.
  • Related resources are less structured than in newer versions.
  • There is no general custom response field selection.
  • There is no general Upsert support.

API v2

API v2 builds on v1 and adds more structured data handling, better response shaping, and more consistent behavior for larger integrations.

Major differences from v1

  • Structured lookup output: Lookup fields return a JSON object rather than just the display text.
  • Custom response fields: You can request only selected fields instead of always getting the full object.
  • Attached module custom fields: Some endpoints can include custom fields from related records.
  • Hierarchical resource patterns: Nested resources are more common.
  • Upsert support: Some POST endpoints support create-or-update behavior through update and update_data parameters. update  identifies how to search for an existing record. update_data  allows for a different PATCH data definition when compared with the POST data otherwise included. If update_data  is not included, the same data is used for both POST and PATCH actions. This will have different results - 201 vs 200 responses, and will report errors if more than 1 record is present in the update match.
  • Improved permission enforcement: Case restrictions and related authorization rules are enforced more consistently.

Example lookup difference

In v1, a lookup-backed field might look like this:

{ "client_gender": "Male" }

In v2, the same kind of field is typically returned as a structured object:

{ "client_gender": { 
    "lookup_value_id": 100156, 
    "lookup_value_name": "Male", 
    "lookup_value_uuid": "22b9854d-cbbc-430f-ad9c-bb580bcb447c", 
    "lookup_type_name": "Genders", 
    "lookup_type_table_name": "gender", 
    "lookup_type_custom": false, 
    "lookup_type_uuid": null 
    } 
}  

That additional metadata makes it easier to discover valid values through the lookup APIs without guessing at the list of accepted choices.

Metaparameters in v2

V2 accepts both traditional and $-prefixed metaparameter names.

For example, both of these styles may work depending on the endpoint:

page_size=10 
$page_size=10

However, you should not send both forms in the same request.

API v3

API v3 builds on v2, but it changes the default contract in ways that are especially helpful for large data syncs, selective field retrieval, and clients that want tighter control over response size.

Major differences from v2

  • Minimal responses by default: If you do not ask for fields, you only get the primary UUID back.
  • Strict $ metaparameters: Request-control parameters must use the $ prefix.
  • More expressive search: V3 supports semantic search expressions on eligible field types.
  • Cleaner relationship naming: Many relationship fields drop older _id suffixes in the public contract.
  • Sub-object write support: Some nested structures can be created or updated inline with the primary object instead of requiring a sequence of separate API calls.

Why v3 is different

V1 and v2 usually behave like traditional REST APIs that return the full record unless you ask for something else.

V3 is designed with a different default assumption: many integrations do not always need the full object. Returning only the primary UUID unless more fields are requested can reduce response size, speed up large sync jobs, and make it easier to request exactly what your integration needs.

Response shaping in v3

If you do not specify response fields, a v3 response may look like this:

json { "matter_uuid": "e621b2a2-23cb-11df-a45f-00188b3e7804" }

To get the full object, explicitly request it:

http GET /api/v3/matters/e621b2a2-23cb-11df-a45f-00188b3e7804?$response_parameters=*

To get specific fields only:

http GET /api/v3/matters/e621b2a2-23cb-11df-a45f-00188b3e7804?$response_parameters=first,last

This same idea applies to many search responses as well. In v3, it is important to think about the response fields you need rather than assuming the API will always return the full object.

Metaparameters in v3

Metaparameters help define the response. In v3, metaparameters must use the $ prefix.

Examples:

  • $page_size
  • $page_number
  • $sort
  • $response_parameters
  • $custom_results
  • $or
  • $update
  • $update_data
  • $custom_fields

Unprefixed equivalents such as page_size, response_parameters, or or return a 400 Bad Request.

This stricter naming helps separate request-control parameters from actual data fields, which makes searches, response shaping, and Upsert behavior more predictable.

Search expressions in v3

V3 supports richer search expressions for eligible fields.

Examples include:

  • Symbolic comparisons such as @<=2026-06-29
  • Relative keywords such as @today, @yesterday, and @this_month
  • Null checks such as @null and @not_null
  • Ranges such as @between:2026-01-01,2026-01-31
  • Text operators such as @equals:..., @contains:..., @begins:..., and @ends:...

These expressions are available for eligible:

  • date
  • dob
  • numeric
  • timestamp
  • timestamptz
  • text

Not every endpoint or returned field supports every search style. Always refer to the published API docs for the specific endpoint you are using.

As a general rule:

  • date and dob fields support the widest range of expressions.
  • numeric fields support numeric comparisons and numeric ranges.
  • text fields support named text operators such as @equals:..., @contains:..., @begins:..., and @ends:....
  • timestamp and timestamptz fields support time-aware comparisons and ranges.

Legacy bare symbolic operators such as =value or <=value are still useful for date- and number-based searches, but they are not the correct way to express text search behavior in v3. For text fields, use the named text operators instead.

Sub-object write support in v3

One of the biggest functional differences in v3 is support for writing some related records inline with the main record.

In earlier versions, a workflow like this often required multiple requests:

  1. Create or update the main record.
  2. Make one or more additional calls to create or update related child records.

In v3, eligible endpoints can let you send those related structures as part of the same request.

Examples of sub-objects may include:

  • addresses
  • assets
  • assignments
  • expenses
  • income
  • other nested child collections documented on the endpoint

This can simplify integration code and reduce the number of round trips needed to keep related data in sync. Because support is endpoint-specific, always check the endpoint documentation before assuming that a nested object can be written inline.

Validation detail in v3

V3 error responses can provide more structured validation detail than earlier versions.

For example, invalid field values is returned under invalid_values, and those entries can include metadata about the expected field type or lookup context. That can make it easier to detect why a request failed and how to correct it programmatically.

Which version should you use?

  • Use v1 if you need compatibility with older integrations that already depend on it.
  • Use v2 if you want a stable, broadly available API with structured lookup handling and more efficient response options.
  • Use v3 if you are building a new integration, want tighter payload control, benefit from more expressive search behavior, or want to reduce multi-step workflows by using sub-object writes where they are supported.

Next Steps

For full endpoint documentation, request and response schemas, and examples, see apidocs.legalserver.org.

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us