# Best practices for boards

- **Fetch the write guide once, then cache it.** With a key that has `read`, `GET /v1/ingest/board?rows=false` answers every
  column and its format without the rows. Refresh it when a write is refused for an unknown column.
- **Key cells by id in long-lived integrations.** Labels read better, but a column can be renamed;
  its `id` never changes. Labels are fine for scripts you watch.
- **Skip what the system fills.** Columns marked `writable: false` are set by Specter; a cell for one
  is refused.
- **Send people by email.** A person column takes a member's email, resolved to the right account —
  easier than tracking account ids.
- **Send real types.** Numbers as numbers, dates as `YYYY-MM-DD`, choices as one of the column's
  `options` values.
- **Batch, and handle the whole refusal.** A batch is all or nothing; the error lists every bad row
  by its index, so fix them all before resending.
- **Use `external_id` on pages.** Leads and Deals keys dedupe on it, so retries and re-syncs never
  make a second record.
- **Check the receipt.** `coerced` shows values Specter changed on the way in and `ignored` shows
  cells that stored nothing — worth logging while you build.
