What is the Universal API?
The Universal API is a single normalized interface that sits on top of all connected legal platforms.
Instead of calling Clio's /api/v4/contacts, Filevine's /api/core/persons,
and Lead Docket's /api/contacts separately, you call one endpoint:
/api/v1/universal/contacts β and LawLink routes, normalizes, and aggregates everything for you.
π Fan-out Reads (GET)
Omit platform_id on any GET β LawLink fires requests to all connected platforms in parallel
and merges the results. Every record includes a platform_id tag so you know its origin.
Failures on one platform are returned in an errors array β others still succeed.
π― Targeted Writes (POST/PATCH/DELETE)
Write operations always require platform_id. This is a strict rule β
writing to multiple platforms simultaneously is too dangerous to do implicitly.
The adapter maps universal field names to each platform's native format automatically.
π Single Integration
Connect once to LawLink. All 5 platforms are reachable through the same base URL, auth token, and schema.
π Normalized Schema
Every response uses the same field names regardless of platform. first_name is always first_name β never FirstName or attributes.first_name.
π¦ Platform Lineage
Every record carries platform_id and platform so you always know where data came from without extra calls.
π‘οΈ Partial Failure Safe
If Filevine is down but Clio responds, you still get Clio data. Platform errors are isolated in the errors[] array.
Routing Rules
| Method | platform_id provided? | Behaviour |
|---|---|---|
| GET | β Omitted | Fan-out β queries all connected platforms in parallel, merges results |
| GET | β Provided | Targeted read β queries only that platform |
| POST | β Omitted | 400 error β write operations must be explicit |
| POST PATCH DELETE | β Provided | Targeted write β routes to that platform only |
Valid platform_id values:
clio_manage Β· clio_grow Β·
lawmatics Β· filevine Β· lead_docket
π‘ Tip: Use GET /api/v1/universal/connections first to see which platforms
the current user has connected. Only connected platforms participate in fan-out.
Universal Schema
These are the normalized field names returned in every response regardless of which platform the record came from. Write operations accept the same names β the adapter translates them to each platform's native format.
Contact
| Universal Field | Type | Clio | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|---|
id | string | contact.id | data.id | personId.native | Id |
first_name | string | first_name | attributes.first_name | firstName | FirstName |
last_name | string | last_name | attributes.last_name | lastName | LastName |
name | string | name (full) | derived | fullName | derived |
email | string | email_addresses[0].address | attributes.email | emails[0].address | |
phone | string | phone_numbers[0].number | attributes.phone | phones[0].number | MobilePhone |
company | string | company.name | attributes.company | companyName | β |
type | string | type (Person/Company) | β | β | β |
birth_date | string | date_of_birth | attributes.birthdate | BirthDate | Birthdate |
created_at | string | created_at | attributes.created_at | createdDate | CreatedOn |
updated_at | string | updated_at | attributes.updated_at | modifiedDate | LastUpdatedDTM |
Matter
| Universal Field | Type | Clio | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|---|
id | string | matter.id | data.id | projectId.native | Id / LeadId |
description | string | description | attributes.case_title | projectName | Description |
status | string | status | attributes.status | phaseName | Status / StatusName |
client_name | string | client.name | derived first+last | β | FirstName + LastName |
created_at | string | created_at | attributes.created_at | createdDate | DateCreated |
updated_at | string | updated_at | attributes.updated_at | modifiedDate | DateModified |
Task
| Universal Field | Type | Clio | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|---|
id | string | task.id | data.id | taskId.native | Id / TaskId |
name | string | name | attributes.name | subject | Summary |
description | string | description | attributes.description | body | Details |
due_date | string | due_at | attributes.due_date | targetDate | TaskStartDate |
priority | string | priority | attributes.priority | β | β |
status | string | is_completed β open/completed | attributes.status | isCompleted β open/completed | Status |
Note
| Universal Field | Type | Clio | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|---|
id | string | note.id | data.id | noteId.native | Id / NoteId |
subject | string | subject | attributes.name | subject | β |
detail | string | detail / body | attributes.body | body | Text / Note |
created_at | string | created_at | attributes.created_at | createdDate | DateCreated |
Event
| Universal Field | Type | Clio | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|---|
id | string | entry.id | data.id | appointmentId.native | Id |
summary | string | summary / name | attributes.name | title | Summary |
start_at | string (ISO) | start_at | attributes.start_date | startUtc | Date |
end_at | string (ISO) | end_at | attributes.end_date | endUtc | β |
description | string | description | attributes.description | notes | β |
location | string | location | attributes.location | location | Location |
all_day | boolean | all_day | attributes.all_day | allDay | false (always) |
Document (Clio Manage only)
| Universal Field | Type | Clio Manage | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|---|
id | string | document.id | β | β | β |
name | string | name (filename) | β | β | β |
locked | boolean | locked | β | β | β |
matter_id | string | parent.id (Matter) | β | β | β |
folder_id | string | parent.id (Folder) | β | β | β |
contact_id | string | parent.id (Contact) | β | β | β |
category_id | string | document_category.id | β | β | β |
latest_version_uuid | string | latest_document_version.uuid | β | β | β |
latest_version_number | integer | latest_document_version.version_number | β | β | β |
created_at | string (ISO) | created_at | β | β | β |
updated_at | string (ISO) | updated_at | β | β | β |
Write Field Mapping
When you send a write request, you use universal field names. This table shows how each adapts them per platform.
Fields not listed below can be passed in the extra object and will be forwarded as-is.
Contact β Create / Update
| You send | Clio Manage | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|
first_name | first_name | first_name | FirstName | FirstName |
last_name | last_name | last_name | LastName | LastName |
email | email_addresses[0].address | Emails[0].Address | ||
phone | phone_numbers[0].number | phone | Phones[0].Number | MobilePhone |
company | company_name | company | CompanyName | β |
type | type (Person/Company) | β | β | β |
custom_fields | custom_field_values[] | custom_fields[] | CustomFields{} | ContactCustomFields{} |
Matter β Create / Update
| You send | Clio Manage | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|
description | description | case_title | projectName / Description | Description |
status | status string | status string | phase name | StatusId (int) or Status |
client_id | client.id | β | clientId.native | β |
client_name | β | first_name/last_name split | β | β |
Task β Create / Update
| You send | Clio Manage | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|
name | name | name | subject | Summary |
description | description | description | body | Details |
due_date | due_at | due_date | targetDate | TaskStartDate |
priority | priority | priority | β | β |
assignee_id | assignee.id | assignee_id | teamMemberIds[0] | UserAssigned (int) |
matter_id | matter.id | taskable_id | projectId.native | LeadId (int) β required |
task_type | β | β | β | TaskType β required |
Note β Create
| You send | Clio Manage | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|
subject | subject | name | subject | β |
detail | detail | body | body | Text |
matter_id | matter.id | notable_id | projectId.native β required | lead_id β required |
contact_id | contact.id | notable_id (when no matter) | β | β |
Event β Create
| You send | Clio Manage | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|
summary | summary | name | title | β |
start_at | start_at | start_date | startUtc | Date β required |
end_at | end_at | end_date | endUtc | β |
location | location | location | location | Location β required |
calendar_id | calendar.id | β | β | β |
matter_id | matter.id | β | projectId.native β required | lead_id β required |
user_ids | β | user_ids[] | β | β |
attendees | attendees[] | β | Attendees[{UserId:{Native}}] | β |
Document β Upload / Update (Clio Manage only)
| You send | Clio Manage | Notes |
|---|---|---|
file | multipart file | Binary upload via 3-step signed-URL flow (create β PUT S3 β PATCH complete) |
name | name | Filename shown in Clio. Defaults to the uploaded file's filename. |
document_id | version of existing doc | If provided, uploads as a new version of that document instead of creating a new one. |
matter_id | parent: {id, type:"Matter"} | Attach to a matter on create; or move to a matter on update. |
folder_id | parent: {id, type:"Folder"} | Attach to a folder. Mutually exclusive with matter_id and contact_id. |
contact_id | parent: {id, type:"Contact"} | Attach to a contact. Mutually exclusive with the above. |
locked | locked (bool) | Lock/unlock the document for editing. |
restore | restore (bool) | Pass true to restore a trashed document within its 30-day window. |
Platform Capability Matrix
Not every platform supports every operation. Unsupported operations are silently skipped in fan-out. Explicitly requesting an unsupported operation returns a 400 error.
| Entity Β· Operation | Clio Manage | Clio Grow | Lawmatics | Filevine | Lead Docket |
|---|---|---|---|---|---|
| Contacts list | β | β | β | β | β |
| Contacts get | β | β | β | β | β |
| Contacts create | β | β | β | β | β |
| Contacts update | β | β | β | β | β |
| Contacts delete | β | β | β | β | β |
| Contacts check (conflict) | β | β | β | β | β |
| Matters list | β | β | β | β | β |
| Matters get | β | β | β | β | β |
| Matters create | β | β | β | β | β no API |
| Matters update | β | β | β | β | β |
| Matters delete | β | β | β | β | β |
| Tasks list | β | β | β | β | β no list API |
| Tasks get | β | β | β | β | β |
| Tasks create | β | β | β | β | β matter_id + task_type req |
| Tasks update / delete | β | β | β | β | β |
| Notes list | β | β | β | β | β |
| Notes create | β | β | β | β | β matter_id req |
| Notes update / delete | β | β | β | β | β |
| Events list | β | β | β | β matter_id req | β |
| Events create | β | β | β | β matter_id req | β matter_id + location req |
| Events update / delete | β | β | β | β | β |
| Custom Fields list | β | β | β | β | β read-only |
| Documents list | β | β | β | β | β |
| Documents get | β | β | β | β | β |
| Documents upload | β | β | β | β | β |
| Documents update | β rename/move/lock/restore | β | β | β | β |
| Documents delete | β soft-delete (30-day trash) | β | β | β | β |
| Documents get_download_link | β | β | β | β | β |
| Documents read (stream bytes) | β | β | β | β | β |
| Documents list_versions | β | β | β | β | β |
β οΈ Clio Grow β not included in universal fan-out for most entities.
Clio Grow only supports the lead inbox (POST /api/v1/clio/leads) which has no universal equivalent.
All Universal Endpoints
Connections
Contacts
Matters
Tasks
Notes
Events
Custom Fields
Documents (Clio Manage only)
Usage Examples
Fan-out: List contacts across all platforms
Omit platform_id to query every connected platform in parallel.
# Fan-out to all connected platforms
curl -X GET \
"https://app.lawlink.ai/api/v1/universal/contacts?limit=20&query=Smith" \
-H "Authorization: Bearer YOUR_TOKEN"// Normalized fan-out response
{
"items": [
{
"platform_id": "clio_manage",
"id": "12345",
"first_name": "John", "last_name": "Smith",
"email": "john@smith.com", "phone": "+15551234567"
},
{
"platform_id": "lead_docket",
"id": "456",
"first_name": "John", "last_name": "Smith",
"email": "jsmith@firm.com", "phone": "+15559876543"
}
],
"total": 2
}Targeted read: Get contacts from Filevine only
Pass platform_id=filevine to restrict the query to one platform.
curl -X GET \
"https://app.lawlink.ai/api/v1/universal/contacts?platform_id=filevine&limit=50" \
-H "Authorization: Bearer YOUR_TOKEN"Targeted write: Create a contact in Clio Manage
platform_id is mandatory for writes. The adapter maps email β email_addresses[0].address automatically.
curl -X POST \
"https://app.lawlink.ai/api/v1/universal/contacts" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"platform_id": "clio_manage",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@example.com",
"phone": "+15551234567"
}'Create a task on Lead Docket
Lead Docket tasks require matter_id (Lead ID), assignee_id (User ID), task_type, and due_date.
β οΈ Lead Docket only: task_type must be one of FollowUp Β· Mailing Β· Administrative
curl -X POST \
"https://app.lawlink.ai/api/v1/universal/tasks" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"platform_id": "lead_docket",
"name": "Follow up call",
"matter_id": "78901",
"assignee_id": "42",
"task_type": "FollowUp",
"due_date": "2026-04-01"
}'Create a note on Filevine (matter_id required)
Filevine and Lead Docket notes must be attached to a matter. matter_id is the projectId.native integer.
curl -X POST \
"https://app.lawlink.ai/api/v1/universal/notes" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"platform_id": "filevine",
"subject": "Client call summary",
"detail": "Discussed timeline. Client agrees to proceed.",
"matter_id": "123456"
}'Handling partial failures in fan-out
When one platform errors, the rest still succeed. Check the errors array alongside items.
// Partial failure response β Filevine errored, Clio succeeded
{
"items": [
{ "platform_id": "clio_manage", "id": "111", "first_name": "Jane", ... }
],
"total": 1,
"errors": [
{
"platform": "Filevine",
"platform_id": "filevine",
"error": "502: Platform returned an error"
}
]
}List documents (Clio Manage)
Documents are only supported by Clio Manage β always pass platform_id=clio_manage. You can filter by matter, folder, or contact, and search by name.
βΉοΈ No fan-out: The document endpoints do not fan-out to other platforms. Omitting platform_id will return a 400 error.
# List documents attached to a matter
curl -X GET \
"https://app.lawlink.ai/api/v1/universal/documents?platform_id=clio_manage&matter_id=88231&limit=25" \
-H "Authorization: Bearer YOUR_TOKEN"// Response
{
"platform": "clio_manage",
"platform_id": "clio_manage",
"data": [
{
"id": "5012334",
"name": "Settlement Agreement.pdf",
"locked": false,
"matter_id": "88231",
"latest_version_number": 3,
"created_at": "2026-03-10T09:15:00Z",
"updated_at": "2026-04-01T14:22:00Z"
}
]
}Upload a new document to Clio Manage
Use multipart/form-data. Optionally pass document_id to create a new version of an existing document instead of a brand-new one. The upload uses Clio's 3-step signed-URL flow internally.
# Upload a new document attached to matter 88231
curl -X POST \
"https://app.lawlink.ai/api/v1/universal/documents/upload" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "platform_id=clio_manage" \
-F "name=Engagement Letter.pdf" \
-F "matter_id=88231" \
-F "file=@/path/to/engagement_letter.pdf;type=application/pdf"# Upload as a new version of document 5012334
curl -X POST \
"https://app.lawlink.ai/api/v1/universal/documents/upload" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "platform_id=clio_manage" \
-F "document_id=5012334" \
-F "file=@/path/to/settlement_v4.pdf;type=application/pdf"Get a signed download URL
Returns a time-limited signed URL for direct download. The URL can be shared with clients or used in browser redirects β no LawLink token required to download the file.
curl -X GET \
"https://app.lawlink.ai/api/v1/universal/documents/5012334/download-link?platform_id=clio_manage" \
-H "Authorization: Bearer YOUR_TOKEN"// Response β copy the URL to download or share
{
"platform": "clio_manage",
"platform_id": "clio_manage",
"data": {
"download_url": "https://app.clio.com/api/v4/documents/5012334/download?token=eyJhb..."
}
}Rename and move a document
Use PATCH to rename or move to a different matter/folder/contact. Only one parent target may be set per request β matter_id, folder_id, and contact_id are mutually exclusive.
β οΈ Single parent only: Providing more than one of matter_id, folder_id, contact_id in the same request returns a 400 error.
curl -X PATCH \
"https://app.lawlink.ai/api/v1/universal/documents/5012334" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"platform_id": "clio_manage",
"name": "Settlement Agreement v4.pdf",
"matter_id": "88231"
}'