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

# Inboxes

> States, data, rendering, layouts, response times and public forms.

An inbox is where one kind of work lands: crash reports, abuse reports, support requests, trial sign-ups. It owns the shape of what your app sends and how each item looks.

```ts theme={null}
import { b, inbox } from "pult"
import { z } from "zod"
import { message } from "../src/messages/message.pult"

export const reports = inbox("reports", {
  icon: "flag",
  resource: message,
  states: ["open", "actioned", "dismissed"],
  reopenOn: "new-occurrence",
  sla: { open: "1h" },
  data: z.object({
    reason: z.enum(["spam", "harassment", "other"]),
    reporter: z.string(),
    body: z.string().max(5000),
  }),
  render: (item) => [
    b.markdown(`> ${item.data.body}`),
    b.fields({
      reason: item.data.reason,
      reports: item.occurrences,
      "last reported": item.lastSeen,
    }),
  ],
})
```

The name (`"reports"`) is the inbox's identity. Rename it and Pult treats it as a new inbox; the old one is archived with its items intact.

## States

`states` lists the states an item moves through, first one first. `closed` says which of them count as done. If you give `states` but not `closed`, every state after the first is closed.

Without `states`, an inbox uses `open`, `in progress` and `handled`, with `handled` closed.

Closed items leave the open list and the sidebar count. In the console, `e` moves an item to the first closed state and `E` reopens it.

## Reopening

`reopenOn: "new-occurrence"` reopens a closed item when your app sends the same fingerprint again, tags it `regressed` and puts it back in front of people. `reopenFrom` limits which closed states reopen; by default all of them do.

## Data and rendering

`data` is a schema for what your app sends. It's validated in your app before anything leaves it, and its type flows into `render`, `title` and everything else that reads `item.data`.

`render` turns an item into [blocks](/build/blocks). It runs in your app when the item is sent, so it can read from your database. `title` builds a title from the data when your app doesn't pass one.

The item passed to `render` also has `occurrences`, `users`, `firstSeen`, `lastSeen` and `due`. These are live values: put them in a block and they stay current as the item changes.

## Linking to a resource

`resource` names the [resource](/build/resources) an item is about. When your app sends `record: user.id`, the item links to that user, shows that user's actions and counts how many different users hit it. Records mentioned in blocks are linked too, so one item can offer actions on several records.

## Layout and columns

`layout` is `"list"` (the default), `"table"` or `"board"`. Boards group items by state and let people drag them between columns.

`columns` picks what tables show: `title`, `state`, `occurrences`, `users`, `lastSeen`, `firstSeen`, `due`, `assignee`, `tags`, or any field of your data as `data.<name>`. In the list layout, `data.*` columns also appear under each title.

```ts theme={null}
columns: ["title", "occurrences", "users", "data.version", "lastSeen"],
```

## Response times

`sla` sets how long an item may sit in a state:

```ts theme={null}
sla: { open: "4h", waiting: "2d" },
```

Durations are minutes, hours or days (`"30m"`, `"4h"`, `"2d"`). Items show when they're due and turn red once overdue, lists can be sorted by due date and filtered to only overdue items, and the sidebar counts them. The `"overdue"` [notification](/build/notifications) trigger tells people when it happens.

## Public forms

`intake` gives the inbox a public form anyone can submit, built from its data schema:

```ts theme={null}
intake: {
  title: "Contact support",
  description: "We usually reply within a day.",
},
```

The form lives at `app.pult.sh/i/<environment>/<inbox>` and is rate limited. Submissions are rendered by your app like anything else.

## Icons

`icon` is one of `archive`, `bot`, `box`, `bug`, `building`, `code`, `flag`, `git-branch`, `hash`, `house`, `inbox`, `life-buoy`, `mail`, `message`, `rocket`, `settings`, `shield`, `user` or `users`. Resources take the same names.


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