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

# Cases

> Respond to information requests Palm raises on a filing — one generic flow handles every case.

export const iconProps = (variant = "default") => {
  const iconVariants = {
    default: "palm-icon-default",
    horizontal: "palm-icon-horizontal",
    stack: "palm-icon-stack",
    navigation: "palm-icon-navigation",
    darkHorizontal: "palm-icon-dark-horizontal",
    dark_stack: "palm-icon-dark-stack",
    getStarted: "palm-icon-get-started"
  };
  return iconVariants[variant] ?? iconVariants.default;
};

export const PalmCard = ({title, description, icon, variant = "default", href, items}) => {
  if (variant === "getStarted") {
    return <div data-card className="pc-wrapper-get-started flex flex-col gap-4 border border-[rgba(4,44,47,0.1)] rounded-2xl p-6">
        <div className="pc-wrapper-inner-get-started">
          {icon !== undefined && <div className="pc-icon-container-get-started">{icon}</div>}
          {title !== undefined && <span className="pc-title-get-started">{title}</span>}
        </div>
        {items && items.length > 0 && <ul className="pc-items-get-started">
            {items.map((item, i) => <li key={i}>
                <a href={item.href} className="pc-item-link-get-started">{item.label}</a>
              </li>)}
          </ul>}
      </div>;
  }
  const variants = {
    default: {
      wrapper: "pc-wrapper-default",
      title: "pc-title",
      description: "pc-description"
    },
    horizontal: {
      wrapper: "pc-wrapper-card",
      title: "pc-title-horizontal",
      description: "pc-description"
    },
    stack: {
      wrapper: "pc-wrapper-stack",
      title: "pc-title-stack",
      description: "pc-description"
    },
    darkHorizontal: {
      wrapper: "pc-wrapper-dark-horizontal",
      title: "pc-title-dark-horizontal",
      description: "pc-description-dark-horizontal"
    },
    navigation: {
      wrapper: "pc-wrapper-navigation",
      title: "pc-title-navigation",
      description: "pc-description-navigation"
    },
    dark_stack: {
      icon: "pc-icon-card",
      title: "pc-title",
      description: "pc-description"
    }
  };
  const styles = variants[variant] ?? variants.default;
  const inner = <a data-card href={href ? href : '#'} className={`no-underline flex flex-col h-full items-start gap-4 p-6 rounded-2xl hover:opacity-80 transition-opacity ${styles.wrapper}`}>
      {icon !== undefined && <span className="icon-wrapper">{icon}</span>}
      {(title !== undefined || description !== undefined) && <div className="flex flex-col min-w-0">
          {title !== undefined && <span className={styles.title}>{title}</span>}
          {description !== undefined && <span className={styles.description}>{description}</span>}
        </div>}
    </a>;
  return inner;
};

A **case** is how Palm requests information it needs to complete a filing. Most filings finish without one. When Palm does need something from you, it opens a case on the filing and notifies you by webhook — your response gives Palm what it needs to finish.

<Note>
  **Early access** — Cases are in preview and may change in backwards-incompatible ways before they are marked stable. [Reach out](mailto:support@getpalm.com) before building on them in production.
</Note>

***

## How cases work

Any time between when you submit a filing and when it completes, Palm may need additional information. When that happens, Palm opens a case on the filing describing exactly what it needs, and you respond with the requested values.

There's no fixed list of cases. Today there's a single kind, `missing_information`, used whenever Palm needs data it doesn't already have — for example:

* Additional information a filing requires that wasn't collected at submission.
* A correction to a value you submitted.
* A clarification needed while the filing is processed.

Because the specifics vary from one filing to the next, each case carries a `request.fields[]` array describing exactly what to collect. Render your form from that array and a single generic handler covers every case — no per-case UI.

## The case object

| Field               | Type     | Description                                                                                   |
| ------------------- | -------- | --------------------------------------------------------------------------------------------- |
| `id`                | string   | Unique case identifier.                                                                       |
| `object`            | string   | Always `case`.                                                                                |
| `parent_type`       | enum     | Resource the case is attached to. `filing` today.                                             |
| `parent_id`         | string   | ID of the parent filing.                                                                      |
| `kind`              | enum     | Type of case. `missing_information` today — determines the shape of `request` and `response`. |
| `status`            | enum     | Lifecycle status. See [Lifecycle](#lifecycle).                                                |
| `summary`           | string   | One-line summary of what's needed.                                                            |
| `details`           | string   | Optional markdown with more context.                                                          |
| `request`           | object   | What Palm is asking for. For `missing_information`, a `fields[]` array.                       |
| `response`          | object   | What you submitted. Present once you've responded.                                            |
| `due_at`            | datetime | When the case is expected to be resolved, if set.                                             |
| `opened_at`         | datetime | When the case was opened.                                                                     |
| `resolved_at`       | datetime | When the case closed, if it has.                                                              |
| `resolution_reason` | enum     | Why the case closed. Set on `resolved` or `superseded`.                                       |

### Request fields

Each entry in `request.fields` tells you everything you need to render one prompt:

| Field         | Type    | Description                                                             |
| ------------- | ------- | ----------------------------------------------------------------------- |
| `name`        | string  | Machine-readable key. Use it as the key in your response.               |
| `type`        | string  | Value type: `string`, `number`, `boolean`, or `date`.                   |
| `description` | string  | Human-readable prompt explaining what's being asked.                    |
| `required`    | boolean | Whether the field must be present in your response. Defaults to `true`. |
| `example`     | any     | Example value showing the expected format.                              |

## Lifecycle

A case has two open states and two terminal states. The status tells you who acts next.

```text theme={null}
needs_response ⇄ under_review → resolved | superseded
```

| Status           | State    | Meaning                                                                            |
| ---------------- | -------- | ---------------------------------------------------------------------------------- |
| `needs_response` | Open     | Your turn — submit a response.                                                     |
| `under_review`   | Open     | Palm's turn — Palm is actioning the case. Nothing needed from you.                 |
| `resolved`       | Terminal | Closed because the work moved forward, typically after your response was actioned. |
| `superseded`     | Terminal | Closed because the parent filing was canceled, completed, or failed first.         |

When a case closes, `resolution_reason` records why: `response_received`, `no_response_needed`, `parent_canceled`, `parent_completed`, or `parent_failed`.

## Webhook events

Each payload's `data.object` is the full case object. See [Webhooks](/developer-guide/webhooks) for delivery, retries, and signature verification.

| Event           | Description                                                                                          |
| --------------- | ---------------------------------------------------------------------------------------------------- |
| `case.opened`   | Palm opened a case and needs your response.                                                          |
| `case.updated`  | An open case changed — for example, your response was received and the case moved to `under_review`. |
| `case.resolved` | The case closed (`resolved` or `superseded`).                                                        |

```json case.opened — JSON wrap theme={null}
{
  "id": "evt_1781661076481_a1b2c3d4e5f6",
  "object": "event",
  "type": "case.opened",
  "mode": "live",
  "created_at": "2026-06-17T01:51:16Z",
  "data": {
    "object": {
      "id": "9b3c1e44-2f6a-4c7d-8e10-2a4b6c8d0e12",
      "object": "case",
      "parent_type": "filing",
      "parent_id": "fil_abc123",
      "kind": "missing_information",
      "status": "needs_response",
      "summary": "Additional information needed to complete your filing.",
      "request": {
        "fields": [
          {
            "name": "corrected_principal_address",
            "type": "string",
            "description": "The principal office address on the filing was incomplete. Provide the full street address.",
            "required": true,
            "example": "123 Main St, Raleigh, NC 27601"
          }
        ]
      },
      "opened_at": "2026-06-17T01:51:16Z"
    }
  }
}
```

## Respond to a case

1. **Receive `case.opened`.** Use the payload, or fetch the case with `GET /v1/case/{case_id}`.
2. **Render prompts from `request.fields`.** Label, type, and required flag are all there.
3. **Submit a response** while the case is in `needs_response`, with a `fields` map keyed by each requested field's `name`:

```bash Bash wrap theme={null}
POST /v1/case/{case_id}/response
```

```json Request body — JSON wrap theme={null}
{
  "response": {
    "fields": {
      "corrected_principal_address": "123 Main St, Raleigh, NC 27601"
    }
  }
}
```

A successful response moves the case to `under_review` and fires `case.updated`. Once the work behind it is done, Palm closes the case and fires `case.resolved`. If Palm needs more, it opens another round on the same filing — each round is recorded for audit purposes.

## Read cases

```bash Bash wrap theme={null}
GET /v1/case/{case_id}
GET /v1/case?parent_type=filing&parent_id={filing_id}&status=needs_response
```

List supports filtering by `parent_type`, `parent_id`, `status`, and `kind`, with cursor-based pagination (`limit`, `cursor`).

## Next steps

<div className="grid lg:grid-cols-2 gap-6 mt-6">
  <PalmCard variant="navigation" title="Form a business" description="State formation filings, end to end." icon={<Icon className={iconProps("navigation")} icon="arrow-right" />} href="/comply/form-a-business" />

  <PalmCard variant="navigation" title="Apply for an EIN" description="Get an EIN from the IRS, standalone or bundled." icon={<Icon className={iconProps("navigation")} icon="arrow-right" />} href="/comply/apply-for-an-ein" />

  <PalmCard variant="navigation" title="Webhooks" description="Delivery, retries, and signature verification for case events." icon={<Icon className={iconProps("navigation")} icon="arrow-right" />} href="/developer-guide/webhooks" />

  <PalmCard variant="navigation" title="Comply overview" description="How filings, cases, and documents fit together." icon={<Icon className={iconProps("navigation")} icon="arrow-right" />} href="/comply/overview" />
</div>
