> For the complete documentation index, see [llms.txt](https://integrate.lexamica.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://integrate.lexamica.com/6.-enrichment-endpoints.md).

# Enrichment Endpoints

Look up Lexamica's directory data—practice areas (case types) and platform law firms—to build richer, self-service integrations.

***

## Table of Contents

1. [Overview](#-overview)
2. [Key Terms](#-key-terms)
3. [How It Works](#️-how-it-works)
4. [Case Type Endpoints](#-case-type-endpoints)
5. [Law Firm Endpoints](#-law-firm-endpoints)
6. [Common Use Cases](#-common-use-cases)
7. [FAQ](#-faq)
8. [Technical Reference](#-technical-reference)

***

## 🎯 Overview

> **📌 TL;DR**
>
> These read-only endpoints let you discover Lexamica's live directory data—the list of case types (practice areas) and the platform's law firms—so you can build dynamic pickers and validate values instead of hard-coding them.

When you send a case to Lexamica, you have to tell us its **case type** (the practice area, e.g. "Personal Injury"). And when you route referrals, you may want to look up a **law firm** by name. Rather than hard-code these values—which drift over time—you can query them live:

* **Search case types** by name or synonym to power a searchable picker
* **Look up a single case type** by its ID or exact name to get its stages and evaluation period
* **List every case type name** to populate a static dropdown or validate a value
* **Search law firms** by name to build a partner directory
* **Look up a single law firm** by ID to fetch its public summary

Because the data is served live from Lexamica, your integration always reflects the current directory—no manual syncing.

***

## 📖 Key Terms

| Term                  | Definition                                                                                             |
| --------------------- | ------------------------------------------------------------------------------------------------------ |
| **Case Type**         | A practice area in Lexamica (e.g., "Personal Injury", "Automobile Accident"). Also called a case type. |
| **Synonym**           | An alternate term that also matches a case type (e.g., "MVA" matches "Automobile Accident").           |
| **Stage**             | A step in a case type's lifecycle (e.g., "Eval Pending", "Open", "Closed With Fee").                   |
| **Evaluation Period** | The standard window a case type allows for evaluation, expressed in days.                              |
| **Law Firm**          | A firm registered on the Lexamica platform. Enrichment returns only its **public summary**.            |
| **Verified Status**   | A law firm's verification state on the platform.                                                       |

***

## ⚙️ How It Works

Every enrichment endpoint follows the same pattern:

```
Enrichment Request Flow
───────────────────────

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Your System   │────▶│   Integration   │────▶│    Lexamica     │
│                 │     │       API       │     │   Directory     │
│ GET case-types  │     │                 │     │                 │
│   /search       │     │ 1. Authenticate │     │ Live case type  │
│                 │     │ 2. Proxy live   │     │ & law firm data │
│                 │◀────│ 3. Shape output │◀────│                 │
│ { success,      │     │    (whitelist)  │     │                 │
│   data: [...] } │     │                 │     │                 │
└─────────────────┘     └─────────────────┘     └─────────────────┘
```

**Key points:**

1. All endpoints live under your organization scope: `/organization/{orgId}/...`
2. They use your **private key** (the same credential as Mappings and Webhook Subscriptions)—see [Organizations and Authentication](/1.-organizations-and-authentication.md)
3. Results are fetched **live** from Lexamica, so they always reflect the current directory
4. Responses are **whitelisted** to a small, stable set of fields—no internal data is exposed
5. Every response uses the standard `{ "success": true, "data": ... }` envelope

> **🎯 Key Takeaway**
>
> These endpoints are for **discovery and validation**, not bulk export. Search endpoints return a capped number of results; use them to power interactive pickers, then look up the selected item by its ID.

***

## 🗂️ Case Type Endpoints

### Search Case Types

Fuzzy-search case types by name or synonym—ideal for a searchable "choose a practice area" field.

**Request:**

```bash
curl -X GET \
  "https://integration.lexamica.com/organization/{orgId}/case-types/search?query=injury&limit=10" \
  -H "Authorization: Bearer your_private_key" \
  -H "Accept: application/json"
```

**Query parameters:**

| Parameter | Type   | Required | Description                                                    |
| --------- | ------ | -------- | -------------------------------------------------------------- |
| `query`   | String | Yes      | Search term, matched against case type names and synonyms.     |
| `limit`   | Number | No       | Max results to return. Defaults to `10` and is capped at `10`. |

> **💡 Tip**
>
> URL-encode multi-word queries: `?query=General%20Injury`.

**Response — `200 OK`** (returns an empty `data` array when nothing matches):

```json
{
  "success": true,
  "data": [
    { "id": "6606eb3d9cbcb8a8697430aa", "name": "Personal Injury", "synonyms": ["PI", "Bodily Injury"] },
    { "id": "6606eb3d9cbcb8a8697430bb", "name": "Automobile Accident", "synonyms": ["Car Accident", "MVA"] }
  ]
}
```

***

### Get a Case Type by ID or Name

Retrieve a single case type's full detail—including its stages and evaluation period—once it's been selected. Accepts either the case type's **ID** or its **exact name**.

**Request:**

```bash
curl -X GET \
  "https://integration.lexamica.com/organization/{orgId}/case-types/General%20Injury" \
  -H "Authorization: Bearer your_private_key" \
  -H "Accept: application/json"
```

**Path parameter:**

| Parameter  | Type   | Description                                                                                  |
| ---------- | ------ | -------------------------------------------------------------------------------------------- |
| `idOrName` | String | A case type ID (Mongo ObjectId) **or** its exact name. URL-encode names that contain spaces. |

> **ℹ️ Note**
>
> Name matching is **exact** (on the name, not synonyms). It trims surrounding whitespace and prefers a case-sensitive match, falling back to case-insensitive. An ambiguous or missing match returns `404`. When in doubt, look up by **ID**.

**Response — `200 OK`:**

```json
{
  "success": true,
  "data": {
    "id": "69679674e89ec60015e9c3f7",
    "name": "General Injury",
    "synonyms": [],
    "stages": [
      { "label": "Eval Pending", "cycle": "evaluating.pending", "inUI": true },
      { "label": "Open", "cycle": "open", "inUI": true },
      { "label": "Closed With Fee", "cycle": "closed.final.withFee", "inUI": true }
    ],
    "evaluationPeriod": { "days": 14, "type": "relative" }
  }
}
```

Returns `404 Not Found` when no case type matches the given ID or name.

***

### List All Case Type Names

Retrieve every case type name as a flat array—perfect for a static dropdown, or to validate a name before calling the detail endpoint.

**Request:**

```bash
curl -X GET \
  "https://integration.lexamica.com/organization/{orgId}/case-types/names" \
  -H "Authorization: Bearer your_private_key" \
  -H "Accept: application/json"
```

**Response — `200 OK`** (returns an empty `data` array when there are none):

```json
{
  "success": true,
  "data": ["3M Earplugs", "ADA - Website Accessibility", "Automobile Accident", "Personal Injury"]
}
```

> **💡 Tip**
>
> This response carries **no IDs**—it's just names. To get a case type's ID, stages, or evaluation period, resolve the name via *Get a Case Type by ID or Name* above.

***

## 🏛️ Law Firm Endpoints

### Search Law Firms

Fuzzy-search platform law firms by name—useful for building a partner directory or a referral-target picker. Results are **public summaries only**.

**Request:**

```bash
curl -X GET \
  "https://integration.lexamica.com/organization/{orgId}/law-firms/search?query=smith&limit=20" \
  -H "Authorization: Bearer your_private_key" \
  -H "Accept: application/json"
```

**Query parameters:**

| Parameter | Type   | Required | Description                                                    |
| --------- | ------ | -------- | -------------------------------------------------------------- |
| `query`   | String | Yes      | Search term, matched against law firm names.                   |
| `limit`   | Number | No       | Max results to return. Defaults to `20` and is capped at `20`. |

**Response — `200 OK`** (returns an empty `data` array when nothing matches):

```json
{
  "success": true,
  "data": [
    { "id": "6606eb3d9cbcb8a8697430aa", "name": "Smith & Associates", "description": "Personal injury specialists serving the Southeast.", "verifiedStatus": "verified" },
    { "id": "6606eb3d9cbcb8a8697430bb", "name": "Doe Legal Group", "description": null, "verifiedStatus": null }
  ]
}
```

***

### Get a Law Firm by ID

Retrieve a single law firm's public summary by its Lexamica ID—for example, after selecting it from search.

**Request:**

```bash
curl -X GET \
  "https://integration.lexamica.com/organization/{orgId}/law-firms/6606eb3d9cbcb8a8697430aa" \
  -H "Authorization: Bearer your_private_key" \
  -H "Accept: application/json"
```

**Response — `200 OK`:**

```json
{
  "success": true,
  "data": {
    "id": "6606eb3d9cbcb8a8697430aa",
    "name": "Smith & Associates",
    "description": "Personal injury specialists serving the Southeast.",
    "verifiedStatus": "verified"
  }
}
```

Returns `404 Not Found` when no firm matches the given ID, or `400 Bad Request` when the ID isn't a valid Lexamica ID.

***

## 📋 Common Use Cases

### 📗 Use Case: A Searchable Practice-Area Picker

|            |                                                                                       |
| ---------- | ------------------------------------------------------------------------------------- |
| **Goal**   | Let a user pick a case type from a live, searchable list before sending a case        |
| **How**    | Call `case-types/search` as the user types, then send the selected `id` with the case |
| **Result** | Users always choose from Lexamica's current practice areas—no stale, hard-coded lists |

**Flow:**

```
1. User types "inj"  ──▶  GET /case-types/search?query=inj
2. Show matching case types in a dropdown
3. User selects "Personal Injury"  ──▶  store its id
4. Send the case with that case type id (see: Inbound Webhooks)
```

***

### 📗 Use Case: Validating a Case Type Before Sending

|            |                                                                             |
| ---------- | --------------------------------------------------------------------------- |
| **Goal**   | Confirm a case type name from your CRM is valid before sending a case       |
| **How**    | Fetch `case-types/names` once and cache it, or call the detail endpoint     |
| **Result** | Catch typos and unmapped values before they cause a case submission to fail |

***

### 📗 Use Case: Building a Referral Partner Directory

|            |                                                                          |
| ---------- | ------------------------------------------------------------------------ |
| **Goal**   | Show a list of platform law firms a user can refer a case to             |
| **How**    | Call `law-firms/search` for the picker, then `law-firms/{id}` for detail |
| **Result** | A live, self-service firm directory without exposing internal firm data  |

***

## ❓ FAQ

### ❓ "Which key do these endpoints use?"

**🔍 Quick Check:**

* ✅ Use your **Private Key**
* ❌ Not your **Public Key** (that one is only for sending data to Lexamica)

**📝 Full Answer:** Enrichment endpoints are management operations, so they use your Private Key—the same key as Mappings and Webhook Subscriptions. See [Organizations and Authentication](/1.-organizations-and-authentication.md) for the two-key model.

***

### ❓ "How many results does search return?"

**📝 Full Answer:** Case type search returns up to **10** results; law firm search returns up to **20**. The `limit` parameter can lower the count but not raise it above the cap. Search is for discovery, not bulk export—if you need the full case type list, use `case-types/names`.

***

### ❓ "Why is `description` or `verifiedStatus` `null` on a law firm?"

**📝 Full Answer:** Those fields are `null` when the firm hasn't set a public description or verification status. The response is whitelisted to `id`, `name`, `description`, and `verifiedStatus`—no other firm data is exposed.

***

### ❓ "Should I look up a case type by name or by ID?"

**📝 Full Answer:** Prefer the **ID** when you have it—it's an exact document lookup and never ambiguous. Name lookup is a convenience: it matches the exact name (trimmed, case-sensitive first), and returns `404` if the name is ambiguous or unknown. Use `case-types/search` to resolve a name to its ID.

***

### ❓ "Is the data cached or live?"

**📝 Full Answer:** It's served **live** from Lexamica, so it always reflects the current directory. There's no need to sync or refresh on your side.

***

## 🔧 Technical Reference

### Endpoint Summary

| Method | Path                                          | Returns                                              |
| ------ | --------------------------------------------- | ---------------------------------------------------- |
| `GET`  | `/organization/{orgId}/case-types/search`     | Array of `{ id, name, synonyms }`                    |
| `GET`  | `/organization/{orgId}/case-types/names`      | Array of case type name strings                      |
| `GET`  | `/organization/{orgId}/case-types/{idOrName}` | `{ id, name, synonyms, stages, evaluationPeriod }`   |
| `GET`  | `/organization/{orgId}/law-firms/search`      | Array of `{ id, name, description, verifiedStatus }` |
| `GET`  | `/organization/{orgId}/law-firms/{id}`        | `{ id, name, description, verifiedStatus }`          |

### Response Fields

**Case type (detail):**

| Field              | Type                       | Description                                                         |
| ------------------ | -------------------------- | ------------------------------------------------------------------- |
| `id`               | String                     | The case type's Lexamica ID—use this when sending cases.            |
| `name`             | String                     | The display name.                                                   |
| `synonyms`         | String\[]                  | Alternate terms that match this case type.                          |
| `stages`           | `{ label, cycle, inUI }[]` | The case type's lifecycle stages.                                   |
| `evaluationPeriod` | `{ days, type }` \| null   | The standard evaluation window; `type` is `relative` or `absolute`. |

**Law firm (summary):**

| Field            | Type           | Description                                                |
| ---------------- | -------------- | ---------------------------------------------------------- |
| `id`             | String         | The law firm's Lexamica ID.                                |
| `name`           | String         | The firm's display name.                                   |
| `description`    | String \| null | The firm's public profile description (`null` when unset). |
| `verifiedStatus` | String \| null | The firm's verification status (`null` when unset).        |

### Status Codes

| Code  | Meaning                                                                      |
| ----- | ---------------------------------------------------------------------------- |
| `200` | Success. Search endpoints return an empty `data` array when nothing matches. |
| `400` | Missing/empty `query`, or an invalid ID.                                     |
| `401` | Missing or invalid credentials.                                              |
| `404` | No case type or law firm matches the given ID or name (detail endpoints).    |
| `429` | Rate limit exceeded.                                                         |

> **🔧 Technical Deep-Dive: Rate Limiting**
>
> Enrichment endpoints are rate limited. Exceeding the limit returns `429 Too Many Requests`. Build a short backoff into interactive pickers (e.g., debounce keystrokes) so a fast typist doesn't trip the limit.

***

*Last updated: July 2026*
