API Versioning
Outline
- Availability
- At a Glance
- Common Concepts
- API v1
- API v2
- API v3
- Which version should you use?
- Next Steps
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
nullto clear a field. - In v3 searches, eligible fields can also use the
@nulland@not_nullsearch 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
updateandupdate_dataparameters.updateidentifies how to search for an existing record.update_dataallows for a different PATCH data definition when compared with the POST data otherwise included. Ifupdate_datais 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 theupdatematch. - 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
_idsuffixes 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
@nulland@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:
datedobnumerictimestamptimestamptztext
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:
dateanddobfields support the widest range of expressions.numericfields support numeric comparisons and numeric ranges.textfields support named text operators such as@equals:...,@contains:...,@begins:..., and@ends:....timestampandtimestamptzfields 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:
- Create or update the main record.
- 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.