> ## Documentation Index
> Fetch the complete documentation index at: https://docs.casepathiq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Create a valid Matter in the CasePath IQ sandbox and safely retry the request.

> [!NOTE]
>
> Sandbox is available at [https://api.sandbox.casepathiq.com](https://api.sandbox.casepathiq.com). Ask your Integration administrator for a scoped Sandbox key; no IP allowlist setup or Microsoft sign-in is needed for API requests. Use synthetic data only.

Inject the Bearer key from your secret manager as `CASE_PATH_IQ_API_KEY`; never paste it into a command or shell history, and keep shell tracing disabled. The examples pass it to curl through standard input so it does not appear in curl's process arguments. Use synthetic data only.

**1. Set your sandbox values**

```bash theme={null}
export CASE_PATH_IQ_BASE_URL="https://api.sandbox.casepathiq.com"
export CLIENT_CODE="SANDBOX"
export CLIENT_REFERENCE_ID="sandbox-developer-001"
```

`SANDBOX` is the Client code for the developer test Integration. Use the Client code supplied with your key if it differs.

Keep the client reference ID stable. It must be unique within your Source integration and Client and contain 1–128 characters from `A-Z`, `a-z`, `0-9`, period, underscore, and hyphen. Do not put names, account numbers, or other personal data in it.

**2. Create a Matter**

```bash theme={null}
printf 'oauth2-bearer = "%s"\n' "$CASE_PATH_IQ_API_KEY" | \
curl --disable --config - \
  --request PUT \
  --url "$CASE_PATH_IQ_BASE_URL/v1/clients/$CLIENT_CODE/matters/by-client-reference/$CLIENT_REFERENCE_ID" \
  --header 'Content-Type: application/json' \
  --header 'If-None-Match: *' \
  --data '{
    "clientCode": "'"$CLIENT_CODE"'",
    "clientReferenceId": "'"$CLIENT_REFERENCE_ID"'",
    "matterType": "debt_recovery",
    "parties": [
      {
        "role": "debtor",
        "type": "person",
        "isPrimaryLiable": true,
        "name": {
          "givenName": "Synthetic",
          "familyName": "Developer"
        },
        "customerNumber": "C-99102",
        "addresses": [
          {
            "type": "correspondence",
            "line1": "12 Example Street",
            "city": "Tallaght",
            "state": "Dublin",
            "countryCode": "IE"
          }
        ],
        "emails": [],
        "phones": []
      }
    ],
    "debt": {
      "type": "commercial_rates",
      "currency": "EUR",
      "outstandingAmount": "1250.00"
    },
    "instruction": {
      "summary": "Synthetic Sandbox developer test",
      "requestedAction": "review_only"
    }
  }'
```

`If-None-Match: *` says this Matter must not already exist. A first successful request returns `201 Created`, a `Location` header, an `ETag`, and the current partner-facing Matter representation.

If the client reference ID already has a Matter, the request returns `412 Precondition Failed` without changing anything — read it and reconcile instead of replaying the create.

For a Matter with several liable Parties, add another entry to `parties[]` with `isPrimaryLiable: false` and its own correspondence address. One instructed file stays one Matter, and `debt.outstandingAmount` stays the single total.

**3. Keep the server-owned identifiers**

Persist these response fields with your integration record:

| Field | Why it matters |
| - | - |
| `matterId` | CasePath IQ identifier for direct reads |
| `sourceRevisionId` | Current server-owned Source revision; response-only |
| `etag` | Precondition for your next write; send it as `If-Match`. Also returned as the `ETag` header |
| `lifecycleStateId` | Required predecessor for the next lifecycle command |
| `status` and `intakeStatus` | Current partner-visible operational state |
| `updatedAt` | Time of this Matter's latest partner-visible change; do not use one Matter's value as a sync watermark |

Every response also includes `X-Request-Id` for support correlation and `Cache-Control: no-store`.

Use the [incremental synchronization guide](https://docs.casepathiq.com/synchronization.md) to capture and advance a run-level watermark.

**4. Retry a lost response safely**

If the connection drops during a create, do not replay it blindly. Retrying with `If-None-Match: *` returns `412` once a Matter exists at that client reference ID — but that is not proof the create was yours, so GET the Matter and reconcile its ownership and content before carrying on.

For an update, send the same PUT with the same `If-Match` tag. That returns `200 OK` with the same `sourceRevisionId` and unchanged `updatedAt` only while the tag is still current — that is, while your first attempt did not commit. If it did commit, it minted a new tag, so the retry carries a stale one and returns `412`. A stale tag is also what you get when another writer intervened. So a `412` here does not tell you which happened: GET the Matter, compare it with what you sent, and re-send only if your update is genuinely not there.

Do not add an `Idempotency-Key` or a caller revision; the precondition is the ordering mechanism.

**5. Update it conditionally**

```bash theme={null}
printf 'oauth2-bearer = "%s"\n' "$CASE_PATH_IQ_API_KEY" | \
curl --disable --config - \
  --request PATCH \
  --url "$CASE_PATH_IQ_BASE_URL/v1/clients/$CLIENT_CODE/matters/by-client-reference/$CLIENT_REFERENCE_ID" \
  --header 'Content-Type: application/merge-patch+json' \
  --header 'If-Match: <etag-from-the-create-response>' \
  --data '{
    "instruction": {
      "historyNotes": "Updated instruction received from the Local Authority"
    }
  }'
```

Replace the placeholder with the `etag` value exactly as returned, including the quote characters that are part of the value — so `"m1-7f3a9c2b"` is sent as `If-Match: "m1-7f3a9c2b"`.

Omitting `If-Match` returns `428 Precondition Required`. A stale tag returns `412 Precondition Failed`. Neither mutates anything.

**6. Read the current Matter**

```bash theme={null}
printf 'oauth2-bearer = "%s"\n' "$CASE_PATH_IQ_API_KEY" | \
curl --disable --config - \
  --request GET \
  --url "$CASE_PATH_IQ_BASE_URL/v1/clients/$CLIENT_CODE/matters/by-client-reference/$CLIENT_REFERENCE_ID" \
  --silent --show-error
```

Use this read before reconciling a conflict or submitting a lifecycle command.

**7. Pull changed Matter state**

```bash theme={null}
export UPDATED_SINCE="2026-09-01T00:00:00Z"

printf 'oauth2-bearer = "%s"\n' "$CASE_PATH_IQ_API_KEY" | \
curl --disable --config - \
  --url "$CASE_PATH_IQ_BASE_URL/v1/matters?clientCode=$CLIENT_CODE&updatedSince=$UPDATED_SINCE&limit=100" \
  --silent --show-error
```

`updatedSince` is required and inclusive. Follow `nextPageToken` until it is `null`; that final page also carries `syncedThrough`, the boundary for your next run. Store it only once every page has been applied, and send it back unchanged as the next `updatedSince` — do not add an overlap of your own.

Each item carries `etag`, `lifecycle` and `payments`, so you can reconcile a paused or closed Matter and its observed payments from the list page, and issue a detail GET only where `etag` differs from the tag you stored.

## Next

* [Understand the domain model](https://docs.casepathiq.com/concepts.md)
* [Choose PUT or PATCH](https://docs.casepathiq.com/matters.md#put-or-patch)
* [Implement incremental sync](https://docs.casepathiq.com/synchronization.md)
* [Handle errors and retries](https://docs.casepathiq.com/errors-and-retries.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.