Blog

Track Every Status Change in Quickbase with a History Table

A Quickbase field only holds its latest value. Here's how to keep a full, reportable history of status changes with a child table and a pipeline, or a simpler append-only text log.

Track every status change: Quickbase history table and pipeline

A common question in the Quickbase community: "I want one Status field, but I also want to see every value it has ever had. How do I keep the history?" A field on a record holds one value. Each save replaces the last one. To keep the history, store each change somewhere else.

This guide covers two ways to do that:

  1. A child history table filled by a pipeline. Use this when you need history you can report on.
  2. An append-only multi-line text field. Use this when a running note on the form is enough.

Source: Using one field to collect data multiple times on the Quickbase Community (our answer).

Flow: a Status change on Projects fires a pipeline that creates a row in Status History

Why two "previous/current" fields don't work

People often try adding a "Previous Status" field next to "Status" and copying one into the other. That keeps exactly one step of history. On the next change the old previous value is overwritten too. To see a full audit trail you need one record per change, and that means a child table.

Step 1: Build the history table

We built this in a sandbox app with the Quickbase JSON API. You can do the same thing in the UI.

Parent table: Projects

FieldType
Project NameText
StatusText - Multiple Choice (Not Started, In Progress, On Hold, Complete)
Status NotesText - Multi-line, "Log the edits to this field" on (optional, see Option B)

Child table: Status History

FieldType
Previous StatusText
New StatusText
Changed ByUser
Changed OnDate / Time
Related ProjectNumeric (reference field from the relationship)

Next, create a one-to-many relationship from Projects to Status History. If you want, add a COUNT summary field ("# Status Changes") to Projects so you can see how many times a project has moved.

The same setup through the JSON API:

# Child field
curl -X POST "https://api.quickbase.com/v1/fields?tableId=<historyTableId>" \
  -H "QB-Realm-Hostname: <realm>.quickbase.com" \
  -H "Authorization: QB-USER-TOKEN <token>" \
  -H "Content-Type: application/json" \
  -d '{"label":"Previous Status","fieldType":"text"}'

# Relationship, with Project Name as a lookup
curl -X POST "https://api.quickbase.com/v1/tables/<historyTableId>/relationship" \
  -H "..." -d '{"parentTableId":"<projectsTableId>","lookupFieldIds":[6]}'

# Add a COUNT summary to the existing relationship
curl -X POST "https://api.quickbase.com/v1/tables/<historyTableId>/relationship/<relationshipId>" \
  -H "..." -d '{"summaryFields":[{"label":"# Status Changes","accumulationType":"COUNT"}]}'

Two things we ran into while testing:

  • choices is rejected on a plain text field. Use fieldType: "text-multiple-choice" for Status.
  • When you create a COUNT summary, don't pass summaryFid: 3. The API returns "That form of summarization/aggregation cannot be applied to this field." Leave out summaryFid for COUNT.

Step 2: Build the pipeline

These steps follow Quickbase's documented Change Log pattern. Pipelines can't be created through the JSON API, so we did not run this pipeline in our sandbox. Test it in your own app before you rely on it.

  1. Trigger: Quickbase channel → On New Event, on the Projects table.
  2. Set Trigger on Any Field to No. Under Trigger on Any of These Specific Fields, choose Status, plus any other fields you want to track.
  3. Turn On Modify Record on. You can leave On Create on if you want the first status recorded too.
  4. In Specify Fields for Use in Subsequent Steps, include Status. A field that isn't listed here can't be referenced later.
  5. Action: Quickbase → Create Record in Status History, with this field mapping:
History fieldValue
Related Project{{a.id}}
New Status{{a.status}}
Previous Status{{a.$prev.status}}
Changed ByLast Modified By from the trigger
Changed OnDate Modified from the trigger

$prev holds the value from before the edit. That's what lets one pipeline run record both sides of the change.

Step 3: Check the result

To check the table design and the reporting side, we added the rows the pipeline would create and queried them back:

POST /v1/records/query
{
  "from": "<historyTableId>",
  "select": [10, 11, 6, 7, 9],
  "where": "{10.EX.1}",
  "sortBy": [{ "fieldId": 9, "order": "DESC" }]
}

Result, newest first:

ProjectPreviousNewChanged On (UTC)
Warehouse RefreshIn ProgressOn Hold2026-10-26 18:30
Warehouse RefreshNot StartedIn Progress2026-10-26 15:00

The "# Status Changes" summary on the project returned 2. Put an embedded report of Status History on the Project form and you get the full timeline on the record.

Option B: An append-only text log

If you don't need to report on the history, use a Text - Multi-line field with Log the edits to this field turned on. Quickbase keeps every entry and stamps it with the date and user. We tested this through the API by writing three notes to the same field. The stored value was:

[OCT-26-26 Sarah Lee] Kickoff scheduled

[OCT-26-26 Mike Chen] Crew on site

[OCT-26-26 Sarah Lee] Waiting on materials

Each write was added to the log, including writes made through the API. The Status field itself just showed the latest value, "On Hold." The downside is that the log is a single block of text, so you can't filter, chart, or total it the way you can with a history table.

Troubleshooting

  • The pipeline ran but no history row appeared. The usual cause is triggering on every field and then filtering the event out. Trigger only on Status.
  • Previous Status is blank. Make sure Status is listed in Specify Fields for Use in Subsequent Steps. On a newly created record, $prev has nothing in it, which is expected.
  • The pipeline writes to the parent instead of creating a child. If the step is "Update Record" on Projects, you're back to overwriting. It needs to be "Create Record" on Status History.
  • History rows aren't linked to the project. Map Related Project to the trigger's Record ID.
  • Too many rows. If you're tracking several fields, consider one pipeline per field, or a "Field Changed" column, so reports stay readable.

References