# Fieldstub — full content

> Every page of fieldstub.com in one file. Generated 2026-09-18. Canonical HTML at https://fieldstub.com/

Fieldstub captures out-of-scope construction work ("extra work", T&M tickets) from people
who have no Procore seat, and files it into Procore as a Change Event with typed line items
on real budget codes. No app, no login, no seat for the person in the field.

---

# Per project. Everyone in the field is free.

> Fieldstub prices per active project, not per user. Free tier with one project, Team at $299 a month for five active projects, extra projects $25 each. No demo call, no card.

Source: https://fieldstub.com/pricing/  ·  Updated 2026-09-01

## The plans

|  | Free | Team |
|---|---|---|
| Price | **$0** | **$299** / month |
| Active projects | One | Five, then $25 each |
| Tickets | Ten a month | Unlimited |
| Field users | Unlimited | Unlimited |
| Capture with photos and signatures | Yes | Yes |
| Writes real Procore Change Events | Yes | Yes |
| Support | [hello@fieldstub.com](mailto:hello@fieldstub.com) | Someone in your time zone |

Free is enough to prove it on one job. Team is for running it across the company.

One recovered ticket usually covers the year. That is the entire business case and we are not going to dress it up.

## Why per project

The people filling in tickets are foremen, subcontractor crews, and whoever happens to be standing next to the extra work. Most of them will be off the job in six weeks and none of them should need a license. Per-seat pricing would make every one of them a purchasing decision, and the predictable result is that the field stops being asked to use it.

A project is the thing you actually run, so it is the thing you pay for. The line between the plans is how many jobs are live and how many tickets you push through, not which features you get: everything in the product is in both plans.

## What you need on the Procore side

Fieldstub writes Change Events, and Change Events lives inside [Project Financials](https://support.procore.com/products/online/financial-management-user-guides). Your Procore account and its modules are licensed from Procore separately; we do not resell any of it.

On a project without Project Financials, tickets are still captured and approving files the record to the Procore daily log instead. [What that is worth, in full.](https://fieldstub.com/extra-work-without-project-financials/)

## Questions

### Is there a demo call?

Only if you want one. Tell us the job you want to try it on and we will get you set up, usually the same day. The one step that needs someone on your side is a Procore admin installing the app, which is a single approval.

### Do I need a card to start?

No. The free tier is a real tier, not a trial: one project, ten tickets a month, full capture, real Change Events. It does not expire.

### Do subcontractors or field crews ever pay?

No, and they never create an account either. Anyone with the capture link can submit a ticket from their phone. The company that installs Fieldstub in its Procore is the only party that pays anything.

### What happens when a job ends?

Revoke the project's capture link and the project stops taking tickets. Change Events already written stay in your Procore; they are your records.

## Related

- https://fieldstub.com/tm-tickets-in-procore.md
- https://fieldstub.com/docs/install.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# T&M tickets, and how extra work actually gets billed

> What a T&M ticket is, the names it goes by, the four fields that make one enforceable, and the paths from a signed ticket to a Procore change order.

Source: https://fieldstub.com/t-and-m-tickets/  ·  Updated 2026-09-01

A T&M ticket, time and materials, is the record of work that was not in the contract: what happened, who directed it, the labor, equipment and materials it took, signed by somebody with authority on the day it happened. Its whole job is to make extra work billable later.

This page is the map. What the document is, what it has to carry to survive an argument, and every route from a signed ticket to money in a change order, with or without software.

## One document, several names

The industry has never settled on a word for this piece of paper. Depending on the region and the contract you will hear:

- **T&M ticket** or **time and materials ticket**, the most common name in the US
- **Extra work order** or **extra work ticket**, common on the office side of the same job
- **Extra work authorization**, when the form leads with the approval rather than the record
- **Force account**, the term on US public works and DOT jobs, where the owner directs the work and the record requirements are stricter
- **Dayworks sheet**, the same document in the UK, Australia and New Zealand

They are one object. A dated record of directed, out-of-contract work, priced from time and materials, signed in the field.

## What one has to carry

Most of the form is bookkeeping: project, date, trade, hours, quantities. Four fields are the argument, and they are the ones most often left blank:

- **Directed by**, with a name and a title. Extra work is only extra if somebody with authority asked for it.
- **How it was directed**. Verbal, email, RFI, bulletin. One word, and six months later it is the paper trail.
- **Why it is not in the contract**. Not what the crew did, but why it was not already someone's job.
- **Signed on site, the same day**. A signature collected later is a signature from somebody who was not there.

The [template page](https://fieldstub.com/tm-ticket-template/) has the full form, field by field, free and with nothing to sign up for, and the longer version of why those four fields decide whether the ticket holds.

![A phone showing the Fieldstub capture form on step one of five, headed "What work happened?". The person is dictating: the answer box is outlined, tagged LISTENING with a level meter beside it, and the transcript reads "Removed an unmarked concrete footing at grid C-4. It was not on the drawings and it was blocking the pile cap." The button at the bottom of the screen reads "Listening...". A language switcher in the header offers EN, ES and FR.](https://fieldstub.com/assets/shots/CAP-02.png)

The same four fields, asked one at a time, on a phone with no account. Hold the button and talk, or type. The header switches the whole form between English, Spanish and French.

## Where tickets die

Rarely in the argument. Usually in the logistics. The ticket gets filled in and signed, and then it stays in the truck, or in a photo on a foreman's phone, and never makes it to whoever prices change orders. The work was real, the record was real, and it never became a line in the budget.

That is worth saying plainly because it changes what to fix. A better form does not help a form that never arrives. The fixes that matter are the ones that shorten the distance between the signature and the person who bills.

## From ticket to money, in Procore

On a Procore job the destination is a [Change Event](https://support.procore.com/products/online/user-guide/project-level/change-events): line items on real budget codes, ready to price into a change order. There are four ways to get a ticket there, and only one of them is us:

- [Procore's own T&M Tickets tool](https://fieldstub.com/docs/procore-tm-tickets/), if the person capturing the work has a Procore seat and the mobile app
- Somebody in the office retypes the paper ticket as a change event
- An integration that captures in the field and writes the change event, which is what Fieldstub does
- Paper, scanned and attached to a daily log, which is technically in Procore and financially nowhere

The honest comparison of all four, including the two that do not involve us, is at [how to get T&M tickets into Procore](https://fieldstub.com/tm-tickets-in-procore/).

![The Fieldstub review queue with a ticket open. The heading reads "Chipped out and re-poured the housekeeping pad at grid C-4", directed by Dana Whitfield, project superintendent. Five lines of cost, two labor, one equipment and two materials, each showing the Procore budget code it will be filed against, totalling $2,112.00. Below are the photo attached in the field and the signature collected on site, and the screen ends with Reject and Approve buttons.](https://fieldstub.com/assets/shots/INB-03.png)

The office side. Nothing reaches Procore until somebody here approves it, and every line shows the budget code it will land on before they do.

Two constraints worth knowing before you pick a path. Change Events lives inside Project Financials, and [without that module](https://fieldstub.com/extra-work-without-project-financials/) the best available destination is the daily log, which records the work but bills nothing. And if the people doing your extra work are subcontractors without Procore, [this page](https://fieldstub.com/subcontractor-extra-work-without-procore/) is about what actually works.

## Start here

- [**The T&M ticket template**](https://fieldstub.com/tm-ticket-template/). The whole form, free, no signup.
- [**How to get T&M tickets into Procore**](https://fieldstub.com/tm-tickets-in-procore/). Four options compared.
- [**Extra work when the sub has no Procore**](https://fieldstub.com/subcontractor-extra-work-without-procore/). What works and what the GC sets up.
- [**Extra work without Project Financials**](https://fieldstub.com/extra-work-without-project-financials/). What a daily log can and cannot hold.
- [**Fieldstub**](https://fieldstub.com/). The ticket above, captured on a phone with no app and no login, landing in Procore as a change event. [Prices are published.](https://fieldstub.com/pricing/)

## Questions

### What does T&M stand for?

Time and materials. The ticket records the time (labor and equipment hours) and materials an unplanned piece of work took, so it can be priced and billed from the record rather than from memory.

### Is a T&M ticket the same as a change order?

No. The ticket is the field record; the change order is the contract change it gets priced into. A signed ticket is the evidence a change order is built from. Work that is on a ticket but never priced into a change order is work you did for free.

### Who should sign a T&M ticket?

Somebody with the authority to direct the work, usually the general contractor's superintendent or the owner's representative, on site, the same day. The signature turns the sheet from an assertion into evidence.

### Do you need software for T&M tickets?

No. A paper template works, and ours is free. The part software fixes is not the form, it is the distance: the pad stays in the truck, and the record never reaches whoever prices change orders. If your tickets already arrive, you do not have the problem.

## Related

- https://fieldstub.com/tm-ticket-template.md
- https://fieldstub.com/tm-tickets-in-procore.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Installing Fieldstub in Procore

> How to install Fieldstub in a Procore company, who can sign in, what it reads and writes, and how to remove it. Requires Project Financials.

Source: https://fieldstub.com/docs/install/  ·  Updated 2026-08-31

Installing takes a couple of minutes and there is no account to create. Everything Fieldstub knows about your people comes from your Procore company directory, so there is no user list to set up here and none to maintain later.

You need to be a Procore company administrator to install an app. Change Events lives in [Project Financials](https://support.procore.com/products/online/financial-management-user-guides), so that is what a ticket needs to become one; on a project without it, approving files the signed record to the Procore daily log instead. Procore's own guide to [installing an app](https://support.procore.com/products/online/user-guide/company-level/admin/tutorials/install-app-from-marketplace) covers the Procore side of the install.

## What happens when you install

Fieldstub gets read access to your company directory and your project list, and the ability to write Change Events. It does not create Procore users, it does not consume seats, and it does not send anything to the people in your directory.

Nothing appears inside Procore until somebody in your office approves a ticket. Until then Fieldstub is only reading.

## After installing, three things to do

The first is in Procore; the other two are in Fieldstub.

1. **Permit your projects.** In Procore, open **Company Admin &rarr; App Management &rarr; Fieldstub &rarr; Permissions** and add each project Fieldstub should work on to the **Permitted Projects** list. Project permissions only apply to projects on that list &mdash; skip this and every project-level call is refused.
2. **Sign in.** Go to [app.fieldstub.com/login](https://app.fieldstub.com/login) and enter your work email. You will get a one-time link. There is no password.
3. **Print a capture code.** Open **Capture links**, pick a project, and print the QR code. Tape it inside the gang box or the job trailer.

That is the whole setup. Anyone who scans that code can submit extra work from their phone.

![The Capture links screen in Fieldstub. A project is selected in the left column, and its capture link is shown as a card with the label, the address it opens, a QR code, and Print and Revoke buttons. A line above reads "A printed code is a permanent, unauthenticated credential. Anyone who scans it can send a ticket for that project."](https://fieldstub.com/assets/shots/QR-01.png)

Where the codes live. Print takes you to a sheet sized for a trailer door; Revoke kills the link the moment a job ends or a code walks off.

## Who can sign in

**Anyone in your Procore company directory, and nobody else.** There is no invite flow and no user list inside Fieldstub, on purpose. It would be a second copy of a list you already keep, and it would be wrong the first time somebody left.

So to give a project manager access to the review queue, [add them to your Procore company directory](https://support.procore.com/products/online/user-guide/company-level/directory/tutorials/add-a-user-account-to-the-company-directory). To take it away, remove them there. Changes take effect within a few minutes.

The person *filling in* a ticket is a different matter entirely: they need nothing. No Procore seat, no account, no app, no invitation. They scan the code and type. That is the point of the product, and it is why subcontractors and crews can use it on day one.

> A membership check runs on every request to the office side, not just at sign-in. Somebody removed from your Procore directory loses access to Fieldstub within minutes, without anyone here doing anything.

## Nothing is written to Procore without a person

Every submitted ticket lands in a review queue that works like an inbox: **Needs review**, **In Procore**, **Rejected**. Somebody in your office opens a ticket, checks the line items and the budget code each one will be filed under, and approves it. Only then does Fieldstub write the Change Event.

This exists because of a specific Procore behavior. **Procore accepts a line item with a blank budget code without any warning**. It returns success and the cost quietly lands nowhere. So Fieldstub flags any line it could not route with confidence and refuses to file it blank unless a reviewer explicitly says so. A reviewer can also create a budget code on the project without leaving the queue, for genuinely unbudgeted extra work &mdash; that is a per-company setting in Fieldstub, **off by default**, because on a budget synced from an ERP a new code belongs in the ERP.

On a project without the Change Events tool, approving works differently and never silently: the reviewer is told the project has no Project Financials and must explicitly choose to file the record to the [Procore daily log](https://support.procore.com/products/online/user-guide/project-level/daily-log) instead. A daily log entry is a dated record, not money on a budget code, and the screen says so before anything is written.

Approving is not reversible from Fieldstub. A Change Event in your Procore is a real record, and there is no undo endpoint, which is why approval is a deliberate act by a named person rather than anything automatic.

## Exactly what Fieldstub can reach

The complete list. Every endpoint the application is capable of calling, last audited 31 August 2026. There is nothing else in the client.

| Endpoint | Read or write | Why |
|---|---|---|
| `/companies` | Read | Which companies installed the app |
| `/companies/{id}/users` | Read | The directory. This is the access list |
| `/projects` | Read | The project picker, and checking a project is yours |
| `.../work_breakdown_structure/segments` | Read | Cost codes and cost types, for routing |
| `.../segments/{id}/segment_items` | Read | The same |
| `.../work_breakdown_structure/wbs_codes` | Read | The budget codes a line can be filed to |
| `.../work_breakdown_structure/wbs_codes` | **Write** | Creating a code for unbudgeted extra work, if your company switched that on |
| `/change_events` | Read | Checking whether a ticket was already filed, and whether a project has the Change Events tool at all |
| `/change_events` | **Write** | The change event itself |
| `/change_events/{id}/line_items` | **Write** | Its line items |
| `/change_events/{id}` | **Write** | Attaching the photos |
| `/projects/{id}/vendors` | Read | On a daily-log approval, attributing the log to the right subcontractor |
| `/projects/{id}/manpower_logs` | Read | Checking a daily-log record was not already filed, since Procore does not dedupe these |
| `/projects/{id}/manpower_logs` | **Write** | The daily-log fallback, only where Change Events is absent and only by the reviewer's explicit choice |

Nothing reads your commitments, contracts, drawings or documents. Vendors are read only on a daily-log approval, to name the subcontractor on the log. Nothing modifies your directory. The only things Fieldstub creates in Procore are change events, their line items, their attachments, occasionally a budget code a reviewer asked for, and, on a project without Change Events, a manpower log the reviewer explicitly chose.

## If something is missing

| What you see | What it means |
|---|---|
| Your email is refused at sign-in | That address is not in the Procore company directory, or the install has not finished. Check the directory first |
| No projects in the picker | The Procore account has no active projects the app can see, or the install was scoped to a different company |
| Everything on one project fails | That project is not on the app's Permitted Projects list in Procore. Company Admin &rarr; App Management &rarr; Fieldstub &rarr; Permissions |
| A ticket is stuck in Needs review | That is the normal state. It waits for a person. Nothing expires |
| Approve fails with a routing error | A line has no budget code chosen. Route it, or create a code on the project from the same screen |
| Change Events is missing in Procore | The project does not have Project Financials. Tickets are still captured, and approving offers to file the record to the daily log instead of a change event |

## Removing it

Uninstall the app from Procore and Fieldstub loses all access immediately. The credential is scoped to the install, so there is nothing left for it to read.

Change Events that were already written stay in your Procore. They are your records, created by a person on your team, and removing an integration should not touch your financial history.

## Getting help

Email [hello@fieldstub.com](mailto:hello@fieldstub.com). A real person reads it.

If you are wiring Fieldstub into something else, there is a [REST API](https://fieldstub.com/docs/api/) and an [MCP server](https://fieldstub.com/docs/mcp/), and you can issue keys yourself from Settings.

## Questions

### Do subcontractors need a Procore seat to submit a ticket?

No. They need a phone with a browser. There is no account, no app, no login and no invitation. They scan the QR code and fill in the form. Only the office side, where tickets are reviewed and approved, requires being in your Procore directory.

### How do I give someone access to the review queue?

[Add them to your Procore company directory](https://support.procore.com/products/online/user-guide/company-level/directory/tutorials/add-a-user-account-to-the-company-directory). That is the whole access list. There is no separate user list in Fieldstub. Removing them there removes their access here within a few minutes.

### Does Fieldstub require Project Financials?

For change events, yes, because that is the tool change events live in. On a project without it, tickets are still captured with photos and a signature, and approving files the signed record to the Procore daily log instead. That is a dated record rather than money on a budget code, the reviewer chooses it explicitly every time, and it is never the silent default.

### Can Fieldstub write to Procore without anyone approving it?

No. Every ticket waits in a review queue until a person in your company approves it. There is no automatic path from a submitted ticket to a change event, and there is no setting that creates one.

### What happens to my data if I uninstall?

Fieldstub loses access to your Procore immediately. Change events already written stay in Procore as your records.

## Related

- https://fieldstub.com/tm-tickets-in-procore.md
- https://fieldstub.com/docs/procore-change-events-api.md
- https://fieldstub.com/docs/api.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Procore budget codes, and why your change event line item lands blank

> A Procore change event line item needs a WBS code id. The segment_items form returns 200 and is silently discarded, filing every line under a blank code.

Source: https://fieldstub.com/docs/procore-budget-codes/  ·  Updated 2026-08-09
Verified against a Procore sandbox, August 2026

If you are writing change event line items into Procore through the API and they are all landing on a blank budget code, you have hit a real trap and not a mistake in your data. Procore accepts two shapes for `budget_code`. One works. The other passes validation, returns `200`, and is then thrown away.

This page is what we learned probing the API for Fieldstub. It cost most of an afternoon, and none of it is in the documentation.

## The short version

A line item's budget code must reference an existing **WBS code** by id:

```
"budget_code": { "id": 1870754 }
```

Procore also accepts this, which looks more natural and is wrong:

```
"budget_code": { "segment_items": [ { "segment_id": 1, "segment_item_id": 2 } ] }
```

> **The second form returns 200 and is silently discarded.** Every line item lands on the project's blank WBS code (`flat_code: ""`). Distinct segment items go in, an identical id comes out, and there is no error, no warning, and nothing in the response that says anything went wrong.

That is the worst possible failure mode. An integration built on the `segment_items` form looks correct in testing, writes clean 200s in production, and quietly files every dollar into a bucket nobody reviews.

![A cost table from the Fieldstub review queue for a ticket headed "Chipped out and re-poured the housekeeping pad at grid C-4". Five rows, two labor, one equipment and two materials, and each row has a Budget code column showing a named WBS code: 03-300.L Cast-in-Place Concrete Labor, 03-300.E Equipment and 03-300.M Materials. The rows total $2,112.00, and a line under the table reads "Where each line will be filed in Procore."](https://fieldstub.com/assets/shots/INB-04.png)

Because Procore will not say no, somebody has to. Every line is shown against the WBS code it will be filed under, before anything is written.

## What a budget code actually is in Procore

The naming is the root of the confusion. Three different things get called a code:

| Thing | What it is | Use it for a line item? |
|---|---|---|
| **Cost code** | An entry in the project cost code list, like `01-000`. There are often hundreds. | No |
| **WBS code** | A full work breakdown combination with an id and a `flat_code` like `01-000.E`. This is what Procore calls a budget code. | **Yes** |
| **Budget line item** | A row in the budget. Has its own id, unrelated to the above. | No |

Posting a budget line item id is what named the real entity for us. `budget_code: {id: 160548}` comes back with `Wbs Code with ID 160548 not found`, which is the only place in the whole exchange that says out loud what the field wants.

WBS codes live here:

```
GET /rest/v1.0/projects/{project_id}/work_breakdown_structure/wbs_codes
```

Each carries a `flat_code` that reads as cost code plus cost type letter. `01-000.E` is cost code `01-000`, cost type Equipment. The letters are **L**abor, **M**aterials, **E**quipment, **O**ther.

## The constraint nobody mentions: WBS codes only exist for budgeted combinations

A WBS code is created when a cost code and cost type combination appears in the project budget (Procore's [overview of Work Breakdown Structure](https://support.procore.com/products/online/user-guide/company-level/admin/tutorials/about-work-breakdown-structure) is the background reading, and [creating your project's WBS](https://support.procore.com/products/online/user-guide/project-level/admin/tutorials/create-your-projects-work-breakdown-structure) is the fix when a combination is missing). A cost code with no budget line item **has no WBS code at all**, which means there is nothing valid to point a line item at.

This matters more than it sounds, because extra work is unplanned by definition. The code you need is routinely the one the budget does not have yet. On a real sandbox project with 304 cost codes, a four line ticket routed materials to `09-500.M` and equipment to `01-000.E` cleanly, and both labor lines had nowhere to go, because the project had no budgeted labor code.

There are only three honest options at that point:

1. Route the line to a different code that is budgeted, and accept it is not quite right.
2. Create the budget code first, then route to it.
3. Let it fall to the blank code, which is how costs go missing.

The third one is what happens by default, silently, which is the entire problem.

## Creating a budget code through the API

You can create one, and this is what makes option two above possible:

```
POST /rest/v1.0/projects/{project_id}/work_breakdown_structure/wbs_codes

{ "segment_items": [
    { "segment_id": 12345, "segment_item_id": 67890 },
    { "segment_id": 12346, "segment_item_id": 67891 }
] }
```

The body is **bare**. Wrapping it as `{ "wbs_code": { ... } }` returns `param is missing or the value is empty or invalid: segment_items`, which reads like the field is absent when the real problem is the wrapper.

A WBS code has to name every populated segment, not just the two you care about. If the project has a Sub Job segment with entries, your body needs a Sub Job item in it as well, or the create is rejected.

## If you are building this, do it in this order

1. Read the project's WBS codes once and cache them. They change rarely and every read costs rate limit budget.
2. Resolve each of your lines to a `flat_code` before you write anything, matching on cost code and cost type letter.
3. Treat an unresolved line as a stop, not a default. Never let it fall through to the blank code on its own.
4. Give a human the unresolved ones with the project's real code list in front of them, and let them create a code if the right one does not exist.
5. Write with `budget_code: { id }`, and never with `segment_items`.

That last human step is not a limitation to engineer away. Procore will accept a blank code without complaint, so the only thing standing between an automated write and a mis-filed cost is somebody looking at where the money is about to land.

## Questions

### Why does my line item have a blank budget code with no error?

Almost certainly because the budget_code was sent as segment_items rather than as an id. Procore validates that form, returns 200, discards it, and files the line on the project blank WBS code. Switch to budget_code: { id: wbsCodeId }.

### What is the difference between a cost code and a budget code in Procore?

A cost code is one entry in the project cost code list. A budget code is a full WBS combination, usually cost code plus cost type, with its own id and a flat_code like 01-000.E. Line items reference the budget code, not the cost code.

### Can I create a budget code that is not in the budget?

Yes. POST to the project work_breakdown_structure/wbs_codes endpoint with a bare segment_items body naming every populated segment. This is how you route genuinely unbudgeted extra work rather than forcing it onto a code that is merely close.

### Does this apply to change orders and direct costs too?

The WBS code model is shared across Procore financials, so the same id-not-segment-items rule applies wherever a budget code is referenced. We verified the behavior specifically on change event line items.

## Related

- https://fieldstub.com/docs/procore-budget-code-errors.md
- https://fieldstub.com/docs/procore-change-events-api.md
- https://fieldstub.com/tm-tickets-in-procore.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Trust and security

> What Fieldstub stores, who processes it, how access works, and what we do not have. Field data goes to Fieldstub and then, on your approval, into your own Procore.

Source: https://fieldstub.com/security/  ·  Updated 2026-08-31

Fieldstub is operated by PurelySearch LLC (Delaware, United States). This is the plain account of what we hold, who touches it, and how it is protected. Last updated August 9, 2026.

Fieldstub sits between a jobsite and a Procore account, so it holds two kinds of data that deserve different treatment: information about our customers, and information about people in the field who are not our customers and never signed up for anything.

## The short version

- **We do not sell data.** Not to anyone, for any purpose.
- **We do not train machine-learning models on your tickets, photos or signatures.**
- **The capture form loads no third-party code.** No analytics, no fonts, no CDN, no tracking cookie. The person in the field is not measured.
- **Nothing is written to your Procore without one of your people approving it.**
- **Data is encrypted in transit and at rest**, and we share it only with the four sub-processors listed below.

## Where the data goes

One path, three steps, and it is worth being precise about which system holds what.

1. **The field to Fieldstub.** Somebody scans a capture code and fills in a form in their phone browser. That submission (the work described, labor, equipment, materials, photos, and a signature) is sent over TLS and stored in our database.
2. **Review, inside Fieldstub.** The ticket waits in a queue. Somebody from your company opens it, checks the line items and the budget code each one will be filed to, and approves or rejects it. Until that happens nothing has left our system.
3. **Fieldstub to your Procore.** On approval we create a Change Event in *your* Procore account, with the line items, the photos, and the capture details on the record.

> Procore is not one of our sub-processors, and we are careful about that wording. Procore is your system, holding your data under your agreement with them. When Fieldstub writes a change event it is carrying out an instruction your employee gave, into an account you control.

## What we store

**About your staff**: an email address, taken from your Procore company directory, and the timestamp of their last sign-in. There are no passwords, because there are no passwords in the product: sign-in is a single-use link sent by email.

**About the work**: the ticket. A description, why it was needed, who directed it, labor and equipment and material lines, and a total.

**About people in the field**: this is the part that needs care. A ticket carries the name and role of whoever signed it, an image of the signature they drew, the name of whoever directed the work, and photos. If the phone offers a location and the browser permits it, a photo also carries the coordinates and the time it was taken.

Those people are usually subcontractors or crew who have no Procore seat, no Fieldstub account, and no relationship with us at all. **We hold their data as a processor on behalf of the general contractor**, we use it for nothing except showing that ticket to the reviewer and filing it, and we never build a profile of a person across tickets or across companies. The contractor is the controller and is responsible for telling their field workers what is being collected.

**About usage**: see the analytics section below. It is deliberately thin.

## Access control

**Your Procore company directory is the access list.** There is no separate user list to maintain here, no invite flow, and no way to grant somebody access to your tickets except by putting them in your directory in Procore.

The check runs on every request to the office side, not only at sign-in, so removing somebody in Procore removes them here within minutes. If Procore is unreachable we serve the last known answer rather than locking out an entire company over an outage, which means a stale answer can only ever grant what Procore told us minutes ago, never more.

**Every query is scoped to one company.** Tenant isolation is not a filter applied at the end; the company id is the first argument to every operation in the service layer. A ticket id belonging to another customer does not return a permission error, it returns a 404, because confirming the record exists is itself a leak.

## Security practices

- **Encryption in transit.** All traffic, on both the site and the app, is served over TLS.
- **Encryption at rest.** The application and its database run on Railway, which is SOC 2 Type II and SOC 3 certified and encrypts all data at rest at the storage level, backups included, with nothing for us to switch on. Everything runs in Railway&rsquo;s San Francisco region, in the United States.
- **Nothing identifying goes into the logs.** Log lines carry a masked address, `d*****@company.com`, rather than the real one, so a copy of your staff directory does not accumulate in a hosting provider&rsquo;s log retention. No ticket content, photo, signature or API key is ever logged.
- **No passwords.** Sign-in is a one-time link. Tokens are single use, recorded once redeemed so they cannot be replayed, and expire.
- **API keys are stored as a SHA-256 hash**, never in plaintext, alongside a short non-secret prefix used to find the row before a constant-time comparison. A copy of our database does not give anybody a working key. Keys are revocable and every key is scoped to one company.
- **Least privilege against Procore.** The integration can reach fourteen endpoints and no others. The full list is published on our [install page](https://fieldstub.com/docs/install/) rather than described in general terms.
- **Secrets are never committed to source control**, and the signing key for our published trust manifest lives outside the repository entirely.
- **Security-relevant behavior has tests written as attacks**: forged cookies, replayed sign-in tokens, and requests for the company next door.

## Analytics, and what the field never sends

**The capture form contains no third-party code of any kind.** No analytics script, no web font, no CDN, no tag manager, no cookie. That began as a performance requirement: it has to work on an old Android on one bar of signal. It is now also a privacy property we intend to keep.

Elsewhere we use PostHog, and what reaches it is restricted by an allow-list in the code rather than by intention. Events are named individually and each one declares exactly which properties may travel with it, so a property cannot be added by accident.

**No ticket content is ever sent**: no descriptions, no names, no photographs, no signatures, no amounts. An approved ticket sends the number of lines and how many were unrouted. That is the shape of it.

Where an event is associated with a person, the email address is replaced with a keyed HMAC rather than a plain hash. A plain hash of an email is reversible in practice, because there are only so many plausible addresses at a company; keying it means the analytics vendor cannot turn its own data back into your staff directory.

## Sub-processors

The complete list of third parties that can touch data, each for one defined purpose. We will update this list, and we will aim to tell account holders before a new sub-processor handling customer data takes effect.

| Sub-processor | Purpose | Data | Location |
|---|---|---|---|
| [Railway](https://railway.com/legal/privacy) | Application hosting and the Postgres database | Everything the product stores: tickets, photos, signatures, user email addresses | United States |
| [Resend](https://resend.com/legal/privacy-policy) | Transactional email: sign-in links and notifications | Email address and message content | United States |
| [PostHog](https://posthog.com/privacy) | Product analytics | Pseudonymised identifiers and event counts. No ticket content, no photos, no signatures | United States |
| [Cloudflare](https://www.cloudflare.com/privacypolicy/) | DNS and inbound email routing | DNS resolution, and mail sent to a fieldstub.com address | United States |

Procore is deliberately absent, for the reason given above: it is your system, not our vendor.

## Retention and deletion

Tickets, photos and signatures are kept while your account is active, because the review queue and the record of what was filed are the product.

You can ask us to delete a ticket, a project's worth of tickets, or your entire account at any time by emailing [privacy@fieldstub.com](mailto:privacy@fieldstub.com), and we will confirm when it is done.

Uninstalling the app in Procore cuts our access to your Procore immediately. Change Events already written stay in Procore. They are your records, created by your employee, and removing an integration should not reach into your financial history.

> We do not currently run an automatic retention schedule that deletes old tickets on a timer. If your policy requires one, say so and we will agree a schedule in writing rather than pointing at a page that promises something the software does not do.

## If we go down

Our recovery targets are **four hours to restore service** and **a twenty-four hour worst-case data window**, bounded by our provider&rsquo;s backup schedule. These are targets we work to, not a contractual SLA. We will not sell you one we cannot yet stand behind.

The exposure is smaller than that second number suggests, for a reason worth understanding:

- **Approved tickets are already in your Procore.** Once your reviewer approves, the Change Event, its line items and its photos live in your system. Our copy is a record of what we sent you. If we lost everything, your money would still be where it belongs.
- **Tickets being typed are on the phone.** The capture form saves to the device on every keystroke, so a ticket in progress is not ours to lose.
- **What is genuinely at risk** is the narrow set of tickets submitted but not yet approved.

Restores are rehearsed rather than assumed. The drill restores a backup into a scratch database and checks that photographs came back as real images rather than empty rows, because a photo can restore as a zero-length record while every count still looks correct, and nobody notices until a reviewer opens a ticket months later and the evidence is gone.

## Compliance

- **SOC 2: we do not have one.** No report, no audit in progress. We will publish the status here when that changes, and we will not imply a certification we do not hold.
- **GDPR and CCPA**: you can request access to, correction of, or deletion of personal data at any time. See the [Privacy Policy](https://fieldstub.com/privacy/) for the detail.
- **Data Processing Agreement**: available, and published in full at [/dpa/](https://fieldstub.com/dpa/). Email us if you need a countersigned copy.
- **Insurance and security questionnaires**: send them. We would rather answer a long questionnaire honestly than have you assume.

## Reporting a vulnerability

Email [security@fieldstub.com](mailto:security@fieldstub.com) with what you found and how to reproduce it. We will acknowledge it, work with you in good faith, and tell you when it is fixed. Please give us a chance to fix it before disclosing publicly.

There is no bug bounty. We are a small team and would rather be straight about that than advertise a programme we cannot fund.

Machine-readable contact details are at [/.well-known/security.txt](https://fieldstub.com/.well-known/security.txt).

## Questions

### Do you train AI models on our tickets?

No. Ticket content, photos and signatures are used to show the ticket to your reviewer and to file it into your Procore. They are not used to train models, and they are not sold or shared beyond the four sub-processors listed on this page.

### Is Procore a sub-processor of Fieldstub?

No. Procore is your system, held under your own agreement with Procore. Fieldstub writes a change event into it when one of your people approves a ticket, which is an instruction from you rather than a disclosure to a vendor of ours.

### What happens to a subcontractor who fills in a ticket but has no account?

We store what they submitted (the work, photos, their name and role, and their signature) as a processor on behalf of the general contractor who owns the capture code. We do not create an account for them, do not track them across tickets or companies, and the capture form sets no cookie and loads no third-party script.

### Do you have a SOC 2 report?

No. There is no report and no audit under way. When that changes it will be said on this page.

### Can we get a DPA?

Yes. It is published in full at /dpa/ and forms part of the agreement. Email privacy@fieldstub.com if you need a countersigned copy.

## Related

- https://fieldstub.com/privacy.md
- https://fieldstub.com/dpa.md
- https://fieldstub.com/terms.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# T&M ticket template, and the four fields that decide whether you get paid

> A complete time and materials ticket template, field by field, and the four fields that actually decide whether the extra work gets billed. No signup.

Source: https://fieldstub.com/tm-ticket-template/  ·  Updated 2026-08-29

A time and materials ticket records work that was not in the contract, so that somebody can be paid for it later. Most templates you will find are a grid of hours with a signature line at the bottom. That is the easy part, and it is not the part that fails.

Below is the whole template, every field, and a note on which ones matter when the ticket is questioned six months later. Copy it, retype it into your own form, print it. There is nothing to sign up for.

## The template

Four blocks. Header, the work, the cost, the signature.

```
T&M TICKET / EXTRA WORK ORDER              No. ________

Project ______________________  Job no. __________
Date _________________________  Day _____________
Contractor ___________________  Trade ____________

DIRECTED BY
  Name ______________________  Company __________
  Title _____________________  How ______________
                                (verbal / email / RFI / bulletin)

DESCRIPTION OF WORK
  What happened, and why it is not in the contract:
  ______________________________________________
  ______________________________________________
  Reference (drawing / RFI / CO / spec) ___________

LABOR
  Name              Classification    ST hrs   OT hrs
  ________________  ______________    _____    _____
  ________________  ______________    _____    _____

EQUIPMENT
  Description       Operated / bare   Hours
  ________________  ______________    _____

MATERIALS
  Description       Qty      Unit
  ________________  _____    ______

PHOTOS TAKEN   Y / N     How many _______

SIGNED, ON SITE, THE DAY THE WORK HAPPENED
  Name ______________________  Company __________
  Title _____________________  Date _____________
  Signature _________________________________

RECEIVED BY
  Name ______________________  Date _____________
```

## The four fields that decide it

Most of the template is bookkeeping. Four fields are the argument.

| Field | Why it is the one that matters |
|---|---|
| **Directed by, with a name and a title** | Extra work is only extra if somebody with authority asked for it. A ticket that says the work happened but not who directed it is a record of a cost, not a claim. This is the field most often left blank and the one most often argued about. |
| **How it was directed** | Verbal, email, RFI, bulletin. Six months later nobody remembers. One word here is the difference between a claim with a paper trail and one without. |
| **Why it is not in the contract** | Not what the crew did, but why it was not already someone's job. A reviewer who cannot answer that question sends the ticket back, and by then the crew has moved on. |
| **Signed on site, the same day** | A signature collected later is a signature from somebody who was not there. Date and signature together are what makes the rest of the sheet evidence rather than an assertion. |

> If you only tighten one thing about how your tickets are filled in, make it **Directed by**. Hours can be reconstructed from a timesheet. Authority cannot be reconstructed from anything.

## Classification, not just a name

The labor block asks for a classification next to each name for a reason. When the ticket is priced, the rate comes from the classification, and on prevailing wage work it has to. A list of names with hours is a list somebody else gets to interpret.

The same applies to equipment. **Operated or bare** changes the rate, and it is one word.

## What the template cannot fix

The template is not the problem. Here is what actually happens to a good ticket, filled in correctly, by somebody who did everything right:

1. Something out of scope comes up on a Tuesday. Someone says do it, we will sort it out later.
2. It gets written on a carbon-copy pad in a truck.
3. The pad stays in the truck.
4. At closeout, the contractor cannot substantiate the cost, so the contractor eats it.

Steps 1 and 4 are commercial. Nothing on a form changes them. **Steps 2 and 3 are logistics**, and step 3 is where the money goes. The ticket was filled in. It just was not anywhere the office could see it while the job was still open.

That is worth being precise about, because it explains why swapping one paper template for a nicer paper template changes nothing, and why a photo of a ticket texted to a PM only half works: the photo is not attached to a project, a cost code, or anything that adds up.

## The version that does not stay in the truck

Fieldstub is the same four blocks as a link. Somebody scans a code taped inside the gang box, fills in the form on their own phone, signs on the screen, and it is in the office before they have put the phone away.

- No app to install, no login, no account for the person in the field.
- They do not need a Procore seat, and most of the people doing extra work do not have one.
- Photos and the signature ride with the ticket, and the draft saves as they type, so bad signal does not lose it.
- It waits in a queue until somebody in the office approves it line by line. Nothing reaches the financials on its own.

On approval it lands in the general contractor's Procore as a Change Event with the line items on real budget codes, ready to price into a change order.

If you are on Procore and you want the mechanics rather than the pitch, [how extra work gets into Procore](https://fieldstub.com/tm-tickets-in-procore/) covers every option including the ones that are not us.

## Questions

### What should a T&M ticket include?

Project and job number, date, who directed the work and how, a description of why the work is out of contract, labor with names and classifications and straight or overtime hours, equipment with operated or bare hours, materials with quantities, photos, and a signature collected on site the same day.

### What is the difference between a T&M ticket and a change order?

A T&M ticket records what was actually done on a given day. A change order is the commercial agreement to be paid for it. Tickets are the evidence the change order is priced from, which is why the signature and the authorization matter more than the arithmetic.

### Is a T&M ticket the same as a force account?

Close enough in practice. Force account is the term used on public works and by state DOTs for work directed and paid on actual cost, and the record keeping is usually stricter, with equipment summary records required. The fields are the same fields.

### Who signs a T&M ticket?

Whoever directed the work, or their representative on site, on the day. A signature collected at the end of the week is from somebody who was not there, and it is the first thing questioned when the ticket is disputed.

### Do I need software for T&M tickets?

No. Paper works, and it is what most extra work is still captured on. The failure is not the paper, it is that the paper stays in the truck until after the job closes out.

## Related

- https://fieldstub.com/tm-tickets-in-procore.md
- https://fieldstub.com/subcontractor-extra-work-without-procore.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# How the integration works

> The integration workflow: what Fieldstub reads from Procore, what it writes, and the human approval that sits between a field ticket and a Change Event.

Source: https://fieldstub.com/docs/architecture/  ·  Updated 2026-09-18

One diagram, two lanes, and one gate. If you are evaluating Fieldstub for a Procore account you administer, this is the page that answers what moves, in which direction, and at which point in the day.

## The workflow

![A swimlane diagram in two lanes, reading left to right in time. A header names three personas: a foreman or subcontractor crew who captures the ticket and has no Procore account, a project manager or engineer who reviews and approves, and a Procore company admin who installs the app once, alongside the user story and the integration value. The upper lane is Fieldstub, in six steps: scan the printed code, fill in the ticket, it waits for review, an office user signs in by one-time email link authorized from the Procore directory, the reviewer routes every line to a real budget code, and a person approves. The lower lane is the customer's Procore, and every card in it is triggered only by one of the last three steps: READ Company Directory, READ Projects, READ WBS Codes, CREATE WBS Code only when a reviewer asks for one, CREATE Change Event with its typed line items, UPDATE Change Event to attach the field photographs, and CREATE Manpower Log, the daily-log fallback used only where the Change Events tool is absent and only by the reviewer's explicit choice. Each connector between the lanes carries a label naming the Procore tool it touches. Nothing in Procore is ever deleted.](https://fieldstub.com/assets/architecture.svg)

Also available as a [PDF](https://fieldstub.com/assets/fieldstub-procore-integration.pdf).

## What we read, and why

Three reads, each of which exists to serve the write. We do not read anything that is not needed either to decide who may sign in or to place a line of cost on a real budget code.

| What | Why |
|---|---|
| **Company Directory** | This *is* the access control list. An email address in your Procore directory may sign in to your Fieldstub workspace and nobody else may. We never modify it |
| **Projects** | The project picker, and confirming a capture code belongs to a project you own |
| **Work Breakdown Structure** | Segments, segment items and WBS codes, so each line of a ticket can be proposed against a real budget code rather than a guess |
| **Project Vendors** | Only on a daily-log approval, to attribute the manpower log to the right subcontractor. Never modified |

## What we write, and when

**Only after somebody in your office approves.** There is no automatic path from a submitted ticket to a Change Event and no setting that creates one.

| What | When |
|---|---|
| **Change Event** | On approval. Lives in Project Financials, and carries the cost into the budget and on toward a change order |
| **Line items** | With the change event. Typed, each on a real WBS budget code |
| **Photo attachments** | With the change event |
| **A new WBS code** | Only when a reviewer explicitly routes work the budget has no line for, and only if the company has switched code creation on. It is off by default |
| **A manpower log** | Only on a project without the Change Events tool, and only when the reviewer explicitly chooses the daily log. [What that fallback is worth, in full](https://fieldstub.com/extra-work-without-project-financials/) |

Approving is irreversible from Fieldstub. A Change Event in your Procore is a real financial record and Procore provides no way for us to withdraw one, so corrections happen in Procore.

## Why the gate is the whole design

Procore accepts a line item with a blank budget code. It returns success, and the cost lands nowhere. There is no warning, and nothing in the response tells you it happened.

That single behavior is why Fieldstub has a review queue instead of a sync. Every line is routed before it is filed, anything we could not route with confidence is flagged to the reviewer, and a line can only be filed blank if a person says so out loud.

> The same rule is enforced on our API and MCP server, more strictly. An automated caller cannot file a line that merely matched a plausible code, and the option to accept a blank code does not exist on the agent surface at all. A reviewer looking at the screen can see a flag. An agent cannot.

## The agentic surface

Fieldstub is also an MCP server, so an assistant can draft a ticket from a description of what happened on site and read exactly where the money would land before anyone approves it. That surface gets its own diagram, because the question it has to answer is not what moves between the two systems but what an agent can do and what stops it.

![A layer diagram read top to bottom. At the top an MCP client holding a bearer API key the customer issued, then a dashed trust boundary where that key resolves to exactly one installed Procore company. Below it the Fieldstub MCP server, a hand-written protocol shell with ten tools: five read-only, three that write only to Fieldstub and never to Procore, and two that can reach Procore, of which approve_ticket is marked destructive. No tool talks to Procore itself. Every tool is one call into the shared service layer, which the office review queue and the public REST API also call. Beneath it the Procore client, holding one service-account token in memory and containing fourteen endpoints and nothing else, and at the bottom the customer’s Procore showing the six permitted tools.](https://fieldstub.com/assets/mcp-architecture.svg)

Also available as a [PDF](https://fieldstub.com/assets/fieldstub-procore-mcp-architecture.pdf).

Three things about it are worth saying plainly.

| What | Why it is built that way |
|---|---|
| **No tool talks to Procore** | Every one of the ten is a single call into the same service layer the review queue uses. There is no second implementation of approving a ticket, so the two cannot drift apart on the day one of them gets a fix |
| **The agent surface is narrower than the human one** | The escape hatches a reviewer gets on screen do not exist over MCP. A line with no budget code is refused, a line that merely matched a plausible code is refused, and an agent cannot overturn somebody&rsquo;s rejection |
| **A key is one company** | The bearer key resolves to exactly one installed Procore company, and that id is the first argument to every call beneath it. There is no way to name another |

The key itself is created and revoked by a reviewer in your own Fieldstub queue, stored as a SHA-256 hash, and shown once. When an agent approves a ticket, the audit trail records the credential rather than a person&rsquo;s name, because a person did not do it. The [MCP server guide](https://fieldstub.com/mcp) has the tool list in full.

## Authentication and tenancy

Fieldstub authenticates to Procore as a **Developer Managed Service Account** using OAuth 2.0 client credentials. There is no user-level OAuth: the person in the field has no Procore identity to authenticate as, and the office side is authorized against your directory instead.

Every tenant is a Procore company. The company id is the first argument to every operation in the service layer, so there is no ambient tenant and no default to fall back on, and a request for another company&rsquo;s record returns 404 rather than 403.

The complete list of endpoints we can reach is on the [install page](https://fieldstub.com/docs/install/). There are fourteen, and there is nothing else in the client.

## Questions

### Does anything reach Procore automatically?

No. Every ticket waits in a review queue until a person in your company approves it. There is no automatic path and no setting that creates one.

### Does Fieldstub become the system of record?

No. Procore stays the system of record. Fieldstub captures a document that does not exist in Procore yet, a signed field ticket from somebody without a seat, and files it into Procore. Data moves toward Procore, never away from it. Nothing is exported or warehoused.

### What happens to a field submission if it is never approved?

It stays in the review queue. Nothing expires and nothing is filed. Rejecting it is also a decision a person makes.

### Where is the data held?

In the United States, on Railway, in its San Francisco region. Railway is SOC 2 Type II and SOC 3 certified and encrypts data at rest at the storage level. Full detail on the Trust and security page.

## Related

- https://fieldstub.com/docs/install.md
- https://fieldstub.com/docs/api.md
- https://fieldstub.com/docs/mcp.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Privacy Policy

> How Fieldstub collects, uses, shares and protects personal data, including data about field workers who have no account, which we hold on behalf of the contractor.

Source: https://fieldstub.com/privacy/  ·  Updated 2026-08-09
Effective August 9, 2026

This policy explains how PurelySearch LLC ("Fieldstub", "we", "us") handles personal data on fieldstub.com and app.fieldstub.com (the "Service"). For the plain-language version, including the full list of providers we use, see [Trust and security](https://fieldstub.com/security/).

## 1. Who we are

The Service is operated by PurelySearch LLC, a limited liability company organized in Delaware, United States. For anything on this page, contact [privacy@fieldstub.com](mailto:privacy@fieldstub.com).

## 2. Data we collect from our customers

A Fieldstub customer is a general contractor with a Procore account. From them we hold:

- **Account data**: the email address of each person who signs in, read from your Procore company directory, and the time they last signed in. There are no passwords: sign-in is a single-use link sent by email.
- **Configuration**: the capture links you create, and the project each one belongs to.
- **API keys**: a hash of each key, a short non-secret prefix, who created it and when it was last used. The key itself is never stored.
- **Access requests**: if you ask for access before your company has installed the app, the name, email, company and note you submitted.
- **Usage data**: a thin set of allow-listed product events, described in section 7.
- **Communications**: anything you email us.

## 3. Data we hold about people who are not our users

This section matters more than the last one, and most privacy policies do not have it.

The person who fills in a Fieldstub ticket is usually a subcontractor or a crew member. They have no Procore seat, no Fieldstub account, and no agreement with us. They scanned a code taped inside a gang box. What a submitted ticket can contain about a person is:

- The name and role of whoever signed the ticket, and an image of the signature they drew on the screen
- The name of whoever directed the work
- Photographs of the work, which on a jobsite may include people
- For each photo, the time it was taken and, only if the device offers it and the browser permits it, the coordinates

**For all of this the general contractor is the data controller and Fieldstub is the processor.** We hold it on their behalf, under the [Data Processing Agreement](https://fieldstub.com/dpa/), and we use it for exactly two things: showing the ticket to the reviewer, and filing it into that contractor's Procore when the reviewer approves it.

We do not build a profile of a field worker, link their submissions across tickets or across contractors, market to them, or use their data to improve anything. The capture form sets no cookie, loads no third-party script, and runs no analytics.

If you are a field worker and want to know what was recorded about you, ask the contractor whose code you scanned. They control the record. You can also write to [privacy@fieldstub.com](mailto:privacy@fieldstub.com) and we will help you reach them.

> Location is never required. If the device declines or the browser blocks it, the form carries on without it. A permission prompt has never been allowed to stand between somebody and submitting a ticket.

## 4. How we use data

- To operate and secure the Service
- To decide who may sign in, by checking an address against your Procore company directory
- To show tickets to your reviewers and, on their approval, write change events into your Procore
- To send transactional email: sign-in links and notifications you enable
- To understand how the product is used, at the coarse level described in section 7
- To meet legal obligations and enforce our terms

**We do not sell personal data, and we do not use your tickets, photos or signatures to train machine-learning models.**

## 5. Legal bases (EEA and UK)

Where the GDPR applies, we rely on performance of a contract for providing the Service, legitimate interests for securing and improving it, consent where consent is required, and compliance with legal obligations. For the field data described in section 3 the contractor is the controller and is responsible for establishing a lawful basis and giving notice to the people concerned.

## 6. How we share data

With four sub-processors, each for one defined purpose, listed with what they handle and where on the [Trust and security](https://fieldstub.com/security/) page. We may also disclose data where the law requires it, to protect our rights, or in connection with a business transfer. In that last case we will tell you.

**Writing to your Procore is not sharing in this sense.** Procore is your system under your own agreement with them, and the write happens because one of your people approved a ticket. Procore is not a sub-processor of ours and is deliberately not listed as one.

## 7. Analytics

We use PostHog. What reaches it is restricted by an allow-list in the code: every event is named individually and declares which properties may accompany it, so nothing travels by accident.

**No ticket content is ever sent.** Not descriptions, names, photos, signatures or amounts. An approved ticket sends how many lines it had and how many were unrouted, and nothing else.

Where an event relates to a person, the email address is replaced with a keyed HMAC rather than a plain hash, because a plain hash of an email address can be reversed by guessing. Rotating the key re-pseudonymises everyone, which is intentional.

The marketing site at fieldstub.com uses the standard PostHog browser snippet. **The capture form does not, and never will.**

**Our server logs are masked too.** Where a log line needs to identify somebody it records `d*****@company.com` rather than the address itself, so a copy of your directory does not build up in a hosting provider&rsquo;s log retention. This reduces the exposure; it is not anonymisation, and the domain is still visible.

## 8. Retention

We keep data while your account is active and for a reasonable period afterwards to meet legal and accounting requirements. You can request deletion at any time and we will confirm when it is done.

We do not currently run an automatic schedule that deletes old tickets on a timer. If your policy requires one, we will agree it with you in writing rather than pretend the software already does it.

## 9. Security

Encryption in transit and at rest, no stored passwords, hashed and revocable API keys, per-request access checks against your Procore directory, and tenant isolation enforced in the service layer rather than bolted on. The detail is on the [Trust and security](https://fieldstub.com/security/) page. No system is perfectly secure; report anything you find to [security@fieldstub.com](mailto:security@fieldstub.com).

## 10. Your rights

Depending on where you live you may have the right to access, correct, delete, export, or object to the processing of your personal data. Email [privacy@fieldstub.com](mailto:privacy@fieldstub.com) and we will respond within the time the law allows. California residents have rights under the CCPA including the right to know and the right to delete; we do not sell personal information.

If your request concerns data submitted from a jobsite, we will usually need to route it through the contractor who controls that record, and we will tell you that we are doing so.

## 11. International transfers

We are based in the United States and our sub-processors process data in the United States. If you use the Service from elsewhere, your data will be transferred there. Where personal data comes from the EEA, UK or Switzerland, the parties rely on a lawful transfer mechanism such as the EU Standard Contractual Clauses.

## 12. Children

The Service is not directed at children under 16 and we do not knowingly collect their data.

## 13. Changes

We may update this policy. On a material change we will revise the effective date and, where appropriate, tell account holders. Continuing to use the Service after a change means you accept it.

## 14. Contact

PurelySearch LLC · [privacy@fieldstub.com](mailto:privacy@fieldstub.com)

## Related

- https://fieldstub.com/security.md
- https://fieldstub.com/dpa.md
- https://fieldstub.com/terms.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Every Procore budget code error on a change event line item

> Wbs Code not found, budget_code is missing, must be an integer. Every response Procore gives a change event line item, including two that return 200 and file blank.

Source: https://fieldstub.com/docs/procore-budget-code-errors/  ·  Updated 2026-08-29
Every row posted against a live Procore sandbox on 2026-08-29, change event 447023

If you are posting change event line items into Procore and getting a `400` about a budget code, there are only four errors you can be looking at, and each one means something different. This page has all of them with the exact response body.

The more important half is at the bottom: **two malformed budget codes do not error at all.** They return `200`, the line item is created, and the money lands on a code nobody reviews. If your integration is quiet and your costs are wrong, that is what happened.

## The full matrix

One valid control and five ways to get it wrong, all posted to `POST /rest/v1.0/change_events/{id}/line_items?project_id={project_id}`.

| What you send as budget_code | Status | Response |
|---|---|---|
| `{ "id": 1870754 }` *(a real WBS code)* | **200** | Created, filed correctly. This is the only form that works. |
| `{ "id": 99999999 }` | 400 | `{"errors":{"base":["Wbs Code with ID 99999999 not found"]}}` |
| `{ "id": "not-a-number" }` | 400 | `{"errors":{"params":{"budget_code":{"id":["must be an integer"]}}}}` |
| field omitted entirely | 400 | `{"errors":{"params":{"budget_code":["is missing"]}}}` |
| `{ "segment_items": [...] }` | **200** | **Created, filed blank.** No error, no warning. |
| `{}` *(empty object)* | **200** | **Created, filed blank.** No error, no warning. |

> Read the last two rows again. Procore rejects a budget code that is **absent** and a budget code whose id is **wrong**, but accepts a budget code that is **empty** or **shaped differently**. The validation checks that the field is there and that an id, if present, resolves. It does not check that you actually named a code.

## What each error means

**`budget_code: ["is missing"]`**: you omitted the field. Line items will not be created without it, which is the one place Procore is strict. A bare `cost_code_id` gets the same error, because a cost code is not a budget code.

**`budget_code: {id: ["must be an integer"]}`**: you sent a string. Usually a code read out of a spreadsheet or a query parameter that never got cast.

**`base: ["Wbs Code with ID 99999999 not found"]`**: the most useful error Procore returns, because it is the only place in the whole exchange that names the entity out loud. The field is called `budget_code` and it wants a **WBS code** id. Those are the same thing under two names, and the error is where you find out.

That last one is also what you get if you post a **budget line item** id, which is a different object with its own ids. It looks like a plausible number and it is not the right one.

## The two that do not error

Both of these were created successfully and both landed on the project blank WBS code, id `1870469`, `flat_code: ""`:

```
"budget_code": { "segment_items": [ { "segment_id": 1, "segment_item_id": 2 } ] }
"budget_code": { }
```

The `segment_items` form is the one people reach for, because it mirrors how the work breakdown structure is actually shaped and it is what the WBS endpoints hand you. It is accepted and thrown away.

The empty object is worse, because it is what a serialiser produces when the code you meant to attach was `null`. Nothing in your code is obviously broken. Nothing in the response says anything is wrong. The line item exists, the amount is right, and the cost is filed where nobody looks.

**An integration built on either form passes its own tests.** It writes clean `200`s in production for months, and the first person to notice is whoever reconciles the budget.

![A cost table from the Fieldstub review queue. Five rows of labor, equipment and materials, each showing the named WBS code it will be filed against rather than a blank one: 03-300.L Cast-in-Place Concrete Labor, 03-300.E Equipment, 03-300.M Materials. The rows total $2,112.00 above a line reading "Where each line will be filed in Procore."](https://fieldstub.com/assets/shots/INB-04.png)

The reason a person is in this loop at all. A line with no code cannot be approved by accident, because the API it is going to will take one without complaining.

And the other half of that: a line the router could not place does not quietly go anywhere.

![A ticket in the Fieldstub review queue with one labor line showing "Not routed (do not file)" in its budget code column while the equipment and materials lines carry real codes. A warning below reads "1 line not on a budget code. Procore will accept a blank code with no warning. Tick the box if you really mean to file them blank," with an unticked checkbox labelled "File blank anyway".](https://fieldstub.com/assets/shots/INB-05.png)

The blank code is still reachable, because sometimes it is genuinely what somebody means. It just cannot happen without a person ticking a box that says so.

## How to get a real WBS code id

List them for the project:

```
GET /rest/v1.0/projects/{project_id}/work_breakdown_structure/wbs_codes
```

Each has an `id` and a `flat_code` that reads as cost code plus cost type letter, like `01-000.E`. The letters are **L**abor, **M**aterials, **E**quipment, **O**ther. Post the `id`, not the `flat_code`.

The catch, and it is the one that makes this hard rather than tedious: **a WBS code only exists for a cost code and cost type combination that is already in the budget.** Extra work is unplanned by definition, so the code you need is routinely the one that does not exist yet. [Procore budget codes and the blank code trap](https://fieldstub.com/docs/procore-budget-codes/) covers what to do about that.

## Checking whether it already happened to you

Read your line items back and look at the budget code you got, not the one you sent:

```
GET /rest/v1.0/change_events/{id}/line_items?project_id={project_id}
```

Any line where `budget_code.flat_code` is an empty string is filed blank. If you are seeing your own project blank code id repeated across line items that were meant to be different, that is this bug and not a data problem.

> Assert on the response, not the status. A test that checks for `200` passes on both of the broken forms. A test that checks the returned `budget_code.id` matches the one you sent catches it the first time.

## Questions

### What does "Wbs Code with ID not found" mean in Procore?

The id you sent in budget_code does not match any WBS code on that project. Procore calls the same object a budget code in the field name and a WBS code in the error. List them at /rest/v1.0/projects/{project_id}/work_breakdown_structure/wbs_codes and post the id from there.

### Why is Procore saying budget_code is missing when I sent a cost code?

A cost code is not a budget code. Line items need a WBS code id, which represents a cost code and cost type combination that exists in the project budget. Sending cost_code_id returns the same missing error.

### Why did my change event line item get a blank budget code with no error?

You sent either the segment_items form or an empty object. Both return 200, create the line item, and file it on the project blank WBS code. Verified against a Procore sandbox on 29 August 2026.

### Does Procore validate that a budget code was actually chosen?

No. It validates that the field is present and that an id, if you send one, resolves to a real WBS code. An empty object satisfies both checks and means nothing, so it passes.

## Related

- https://fieldstub.com/docs/procore-budget-codes.md
- https://fieldstub.com/docs/procore-change-events-api.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Creating a Procore change event over the API

> Auth, the create body Procore actually accepts, line items, amounts as strings, attachments, idempotency and rate limits. Probed against a live sandbox.

Source: https://fieldstub.com/docs/procore-change-events-api/  ·  Updated 2026-08-09
Verified against a Procore sandbox, August 2026

Everything below was learned by probing a Procore sandbox rather than by reading the reference, because several of the things the API tells you are not true. Validation errors name fields that do not exist. Paths are not consistent between resources. One request shape returns `200` and throws your data away.

This is the short path from nothing to a change event with typed line items and a photo attached. For the human side of the tool this writes to, Procore's [Change Events guide](https://support.procore.com/products/online/user-guide/project-level/change-events) is the reference.

## Auth: a service account, not per-user OAuth

A Data Management Service Account (DMSA) with `client_credentials` works for reads and writes, which means an integration can run server side on a schedule with nobody logged in.

```
POST https://login.procore.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=...&client_secret=...
```

Two things to know. The body must be form encoded, because JSON is rejected here even though it is accepted elsewhere. And tokens last 5400 seconds, so refresh a little early rather than letting a long request straddle expiry.

Most endpoints also want a `Procore-Company-Id` header. `GET /rest/v1.0/companies` is the useful exception: it answers without one, which is how a multi-company integration finds out which companies it has been installed on in the first place.

## Paths are not consistent, and this is the biggest time sink

Financial resources hang off a `?project_id=` query parameter. Directory-shaped ones nest under `/projects/{id}/`. There is no rule you can infer, so check each one.

| Resource | Path |
|---|---|
| Change events | `/rest/v1.0/change_events?project_id=` |
| Cost codes | `/rest/v1.0/cost_codes?project_id=` |
| Budget views | `/rest/v1.0/budget_views?project_id=` |
| Change event statuses | `/rest/v1.0/change_event/statuses?project_id=` |
| Direct costs | `/rest/v1.0/projects/{id}/direct_costs` |
| Directory, crews, timecards | `/rest/v1.0/projects/{id}/...` |

## Creating the change event

This body works:

```
POST /rest/v1.0/change_events?project_id={project_id}

{ "change_event": {
    "title": "T&M 2026-08-09 — Removed unmarked footing at grid C-4",
    "description": "...",
    "event_scope": "out_of_scope",
    "status": "open",
    "origin_id": "your-own-id",
    "origin_data": "{\"captured\":\"...\"}"
} }
```

> **The validation error lies about the field name.** Omit the status and Procore replies `change_event_status: required`. Send `change_event_status` in any form and it keeps saying required. The field it accepts is `status`. The same pattern shows up on line items, where the wrapper key is `line_item` and not `change_event_line_item`.

`event_scope` takes `in_scope`, `out_of_scope` or `tbd`. `status` takes the lowercase `mapped_to_status` string, not the status id. Statuses are configured per company and carry their own ids, so read the list rather than hardcoding it.

## The empty line item you did not ask for

Creating a change event auto-creates one line item with no content. It **cannot be deleted** (every delete path we tried returns 404) but it **can be patched** into a real one.

```
PATCH /rest/v1.0/change_events/{id}/line_items/{line_item_id}?project_id={project_id}
```

So the first real line should reuse it and the rest should be posted normally. Otherwise every record you write carries a stray $0.00 row, which is exactly the kind of detail that makes a project manager stop trusting an integration.

## Line items, and amounts that must be strings

A line item needs a `budget_code`. A bare `cost_code_id` is rejected with `budget_code: is missing`.

```
POST /rest/v1.0/change_events/{id}/line_items?project_id={project_id}

{ "line_item": {
    "description": "Operator — 6h",
    "budget_code": { "id": 1870754 },
    "cost_impact": { "estimate": {
      "quantity": "6.00",
      "unit_cost": "95.00",
      "calculation_strategy": "automatic"
    } }
} }
```

> **Amounts must be decimal strings.** Send numbers and they post as `null`, with no error. `calculation_strategy` is `automatic` (Procore multiplies quantity by unit cost) or `manual` (you supply a flat `amount`), and nothing else.

`unit_of_measure` validates against a list we never found. Both `hr` and `hour` are rejected, so we omit it.

The read shape is not the write shape. A POST takes and returns `cost_impact.estimate`; a later GET on the change event returns flat `estimated_cost_amount`, `estimated_cost_quantity` and `estimated_cost_unit_cost` on the nested line items. Same numbers, two representations, so parse both.

The `budget_code` field has a trap of its own that is worth its own page: [the segment_items form returns 200 and is silently discarded](https://fieldstub.com/docs/procore-budget-codes/).

## Attachments

Photos ride on a multipart PATCH of the change event itself, not on a separate attachments endpoint.

```
PATCH /rest/v1.0/change_events/{id}?project_id={project_id}
Content-Type: multipart/form-data

attachments[]=@photo.jpg
```

If the provenance matters (when the photo was taken, where, who directed the work) write it into `origin_data` as well. Do not assume EXIF survives the upload.

## Idempotency, and the fact that makes review possible

Set your own `origin_id` on create and you can look the record up later instead of writing a second one. That makes retries safe.

More usefully: **setting `origin_id` does not lock the record.** Procore locks Direct Costs, Sub Invoices, Payments, and approved Commitments and Change Orders, but a change event stays editable after an integration creates it. A PATCH after creation succeeds.

That is a real argument for change events as a write target beyond anything strategic. A record you can correct supports a review loop. A record that freezes on creation does not, and field data always needs correcting.

## Rate limits and a pagination trap

The spike limit is **25 requests per 10 seconds**, and it is easy to hit on a first unthrottled run. Serializing calls roughly 450ms apart stays under it comfortably. The response headers are authoritative, including `x-rate-limit-reset` as a unix timestamp, so respect that before falling back to your own backoff.

> **Pagination is not universal.** WBS `segment_items` ignores `page` and `per_page` entirely and returns the full set on every request. Looping until an empty page produced 5,168 rows for 304 unique records across 17 identical calls. Stop when a page repeats, dedupe by id, and assume any list endpoint might behave this way.

## Questions

### Why does Procore say change_event_status is required when I sent it?

Because the field it accepts is called status. The validation message names a field that does not exist in the request body. Send status with the lowercase mapped_to_status string.

### Why are my line item amounts coming back null?

Amounts under cost_impact.estimate must be decimal strings. Numeric JSON values post as null with no error returned.

### Can a service account write change events without a user logging in?

Yes. A DMSA with client_credentials can read and write server side. Tokens last 5400 seconds and most endpoints want a Procore-Company-Id header.

### Can I write to Procore T&M Tickets instead?

Not through a public API. Twelve resource name variants all 404 and Procore publishes no developer documentation for that tool, so change events is the addressable target.

## Related

- https://fieldstub.com/docs/procore-budget-codes.md
- https://fieldstub.com/docs/procore-tm-tickets.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Terms of Service

> The terms governing use of Fieldstub, operated by PurelySearch LLC. Covers accounts, billing, approvals that write to your Procore, and liability.

Source: https://fieldstub.com/terms/  ·  Updated 2026-08-09
Effective August 9, 2026

These Terms govern your access to and use of fieldstub.com, app.fieldstub.com and the Fieldstub services (the "Service"), operated by PurelySearch LLC ("we", "us"). By using the Service you agree to them. If you do not agree, do not use the Service.

## 1. The Service

Fieldstub captures out-of-scope construction work from people in the field who do not have a Procore seat, holds it in a review queue, and, when one of your people approves it, writes it into your Procore account as a Change Event with line items, photographs and capture details.

The Service includes the web application, the capture form, a REST API and an MCP server.

## 2. Accounts and access

**Access is determined by your Procore company directory.** Anyone in it can sign in; nobody else can. By installing the app you are asking us to treat that directory as the list of people entitled to see your tickets and approve them, and it is your responsibility to keep it current.

You are responsible for activity under your account and for the security of any API key you issue. Tell us promptly about unauthorized use. You must be at least 16 and able to form a binding contract.

The person filling in a ticket in the field has no account and needs none. Anyone holding a valid capture link can submit a ticket to the project it belongs to, which is the point of the product. Treat a capture link accordingly and revoke it when a job ends.

## 3. Plans and billing

- **Free**: one project and ten tickets a month.
- **Team**: $299 a month for five active projects and unlimited tickets, with additional projects at $25 each.
- **Field users are unlimited on every plan.** Billing is per active project and never per person.

Subscriptions are billed in advance and recur until cancelled. Cancelling stops future renewals and you keep access to the end of the paid period. Except where the law requires otherwise, fees are non-refundable. We may change prices prospectively; a change will not affect a period you have already paid for.

## 4. Approvals, and what lands in your Procore

This is the clause that matters most, so it is in plain words.

**Nothing reaches your Procore unless one of your people approves it.** There is no automatic path from a submitted ticket to a Change Event and no setting that creates one.

**An approval is not reversible from Fieldstub.** A Change Event in your Procore is a real financial record and Procore provides no way for us to withdraw one. Corrections happen in Procore.

**You are responsible for the content of what you approve**: the amounts, the line items, and the budget code each line is filed to. Fieldstub proposes a routing and flags every line it could not route with confidence; deciding whether it is right is a judgement your reviewer makes, and it is not one we can make for you.

None of which is a disclaimer of our own defects. If Fieldstub files something other than what your reviewer approved, that is our problem and we will fix it.

## 5. Acceptable use

You agree not to:

- Break the law or infringe anyone's rights using the Service
- Disrupt or overload the Service, or try to gain unauthorized access to it or to another customer's data
- Scrape or systematically extract the Service except through the API we provide for exactly that
- Submit content you have no right to submit, or that is unlawful
- Use a capture link to collect anything other than records of work on the project it belongs to

## 6. Your data, and the people in the field

You own your tickets, photographs, signatures and configuration. You grant us the limited license needed to operate the Service: to store that content, show it to your reviewers, and file approved tickets into your Procore. How we handle it is set out in the [Privacy Policy](https://fieldstub.com/privacy/), the [Trust and security](https://fieldstub.com/security/) page, and the [DPA](https://fieldstub.com/dpa/).

**For personal data about people in the field you are the controller and we are your processor.** Those people (subcontractors, crew, whoever signs a ticket) have no account with us and no way to reach us. So you are responsible for having a lawful basis to collect what your capture codes collect, and for giving those people whatever notice the law where you operate requires. We will help; we cannot do it for you, because we do not know who they are.

## 7. Procore

Fieldstub is not affiliated with, endorsed by, or a product of Procore Technologies, Inc. Your Procore account is governed by your own agreement with Procore, and Change Events lives in Project Financials. Without it, tickets are captured but cannot be filed.

We depend on Procore's API. If Procore changes or withdraws it, our ability to file change events may change with it.

## 8. Third-party services

The Service runs on third-party providers, listed on the [Trust and security](https://fieldstub.com/security/) page. We are not responsible for their own services, and your use of them may be subject to their terms.

## 9. Our intellectual property

The Service (its software, its design, and the look and feel of fieldstub.com) belongs to PurelySearch LLC. These Terms grant you no rights in our trademarks or brand.

## 10. Disclaimers

The Service is provided "as is" and "as available", without warranties of any kind, express or implied, to the fullest extent the law permits. Budget code routing is a suggestion based on what your project budget contains; it is not financial advice and not a guarantee that a cost is coded correctly.

## 11. Limitation of liability

To the fullest extent the law permits, PurelySearch LLC is not liable for indirect, incidental, special, consequential or punitive damages, or for lost profits or data. Our total liability for any claim relating to the Service is limited to what you paid us in the twelve months before the claim.

## 12. Indemnification

You agree to indemnify and hold PurelySearch LLC harmless from claims arising out of your use of the Service or your breach of these Terms.

## 13. Termination

You may stop at any time, and uninstalling the app in Procore ends our access to your Procore immediately. We may suspend or terminate access for a breach of these Terms or to protect the Service. Change Events already written stay in your Procore. Provisions that should survive termination (intellectual property, disclaimers, limitation of liability) do.

## 14. Governing law

These Terms are governed by the laws of the State of Delaware, without regard to conflict-of-laws rules. The exclusive venue for disputes is the state and federal courts of Delaware.

## 15. Changes

We may update these Terms. On a material change we will revise the effective date and, where appropriate, tell account holders. Continued use after a change means you accept it.

## 16. Contact

PurelySearch LLC · [privacy@fieldstub.com](mailto:privacy@fieldstub.com)

## Related

- https://fieldstub.com/security.md
- https://fieldstub.com/privacy.md
- https://fieldstub.com/dpa.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# How to get T&M tickets into Procore

> Procore T&M Tickets, manual change events, an integration, or paper. What each one requires, what lands in the budget, and which people need a Procore seat.

Source: https://fieldstub.com/tm-tickets-in-procore/  ·  Updated 2026-08-09

Extra work gets recorded on a jobsite by whoever is standing there, and the paperwork goes by eight different names depending on the region and the trade: T&M ticket, T&M tag, extra work order, extra work authorization, field work order, force account, dayworks sheet. The problem is the same everywhere. Whatever it is called, it has to end up somewhere that produces a bill.

There are four ways to get it into Procore. Two of them require the person doing the work to have a Procore account, which is usually where the whole thing falls apart.

## The four options, side by side

| Approach | Field needs a seat? | What lands in Procore |
|---|---|---|
| **Procore T&M Tickets** | Yes, plus the mobile app | A T&M ticket record, with no public API to read it |
| **Manual change event** | No, someone in the office retypes it | A change event, as accurate as the retyping |
| **An integration** | Depends entirely on the tool | A change event with typed line items, if it is built properly |
| **Paper or a PDF by email** | No | A file in a folder, or nothing |

The last row is the honest default and by far the most common. It is also what actually competes with everything else here.

## 1. Procore's own T&M Tickets tool

Procore ships this. It captures labor, equipment, materials and a digital signature on a mobile device, and Procore describes it as modernizing the traditional carbon copy forms used on job sites. It is a good tool and it does what it says. [Procore's own guide to it is here.](https://support.procore.com/products/online/user-guide/project-level/tm-tickets)

Two things decide whether it works for you. It **requires a Procore seat and the mobile app** on the person capturing the work. And it has **no public REST API**, so nothing else you own can read those tickets programmatically.

If the people doing your extra work are your own staff and they already carry Procore, this is the obvious answer and you should use it. [More detail on what it needs.](https://fieldstub.com/docs/procore-tm-tickets/)

## 2. Someone in the office types up a change event

Free, works today, and the version most companies are actually running whether or not they would describe it that way.

The failure mode is not the typing. It is the two days between the work happening and the pad arriving in the office, and the fact that the person retyping was not there. What went in the bucket, who authorized it, how long the crew stood waiting: none of that is recoverable a week later, and that detail is the entire value of the record when someone disputes it in the spring.

## 3. An integration that writes change events

Capture in the field, review in the office, write to Procore as a change event with typed line items on real budget codes. This is the category Fieldstub is in, and so is **Clearstory**, which is the established product here.

Whatever you look at, two questions separate a real integration from a form that emails a PDF:

- **Who needs an account?** If the sub or the crew has to be licensed, invited or trained, the tool works on the days when everyone remembers and not on the other days.
- **Where does the money land?** A line item has to reference a real budget code. Procore will accept a blank one without warning, which is [how costs quietly disappear](https://fieldstub.com/docs/procore-budget-codes/). Ask to see what an unroutable line does before someone approves it.

Here is what the second question looks like answered. This is a ticket after somebody in the office approved it, in Fieldstub:

![A ticket in the Fieldstub review queue after approval. A banner across the top reads "In Procore as CE-047" with a link to open it, and on its own line "Approved by jordan.reyes@harborconstruction.com on Thu, Sep 3". Below, three cost lines for a re-poured curb at an ambulance bay, each against a budget code, totalling $3,440.00, followed by the photo taken in the field and the signature collected on site.](https://fieldstub.com/assets/shots/INB-07.png)

The change event number, the link into Procore, and the person who released it. Procore's own audit shows the service account that wrote the change event, because that is what wrote it, so this line is the only record of which human said yes.

And the other end of the same ticket, in Procore:

![Change Event #046 open in Procore, titled "T&M 2026-09-01 — Removed unmarked concrete footing at grid C-4", scope "Out of Scope", with the field photo attached and a description carrying why the work was extra, who directed it, when it was captured and who signed for it. Below, the Line Items table shows two rows against real budget codes: 01-000.L Purpose.Labor, Laborer x2 for 3h at $68.00, $408.00; and 01-000.E Purpose.Equipment, Mini excavator for 3h at $145.00, $435.00.](https://fieldstub.com/assets/shots/PRO-01.png)

Procore's own Change Events tool, showing a ticket that was captured on a phone by somebody with no Procore account. The budget codes on those two lines are the whole game: Procore accepts a blank one without complaining, so a person picked these before anything was written.

## 4. Paper, and why it wins so often

A carbon copy pad costs nothing, needs no signal, works with gloves on, and every single person on the job already knows how to use it. Any replacement that is worse on those four things loses, no matter what it does afterwards.

This is worth saying plainly because it is the reason most field software fails. The comparison is not against another piece of software. It is against a pad that already works.

## What "into Procore" should actually mean

A PDF attached to a [daily log](https://support.procore.com/products/online/user-guide/project-level/daily-log) is technically in Procore. It will not show up in a budget, will not roll into a change order, and will not reach Procore Pay.

The version worth holding out for is a **change event with typed line items, each on a real budget code**, with the photo attached and the provenance on the record: when it was captured, where, and who directed the work. That is the thing that still makes sense in a dispute next spring, and it is the thing that turns into money.

## Questions

### Can a subcontractor submit a T&M ticket without a Procore license?

Not through Procore's own T&M Tickets tool, which requires a seat and the mobile app. A third party capture tool can accept the ticket without an account and write it into the GC's Procore afterwards.

### Does Procore have an API for T&M Tickets?

No public REST API. Twelve resource name variants return 404 and Procore publishes no developer documentation for the tool, so integrations write change events instead.

### Do I need Project Financials to do this?

For change events, yes. [Change Events](https://support.procore.com/products/online/user-guide/project-level/change-events) is part of [Project Financials](https://support.procore.com/products/online/financial-management-user-guides), and without it the write target is not available. It is worth confirming what your Procore account includes before evaluating any tool in this category, including ours.

### What is the difference between a T&M ticket and a change event?

The ticket is the field record of what was done. The change event is the Procore financial object that carries the cost into the budget and on toward a change order. Getting from one to the other is the whole job.

## Related

- https://fieldstub.com/tm-ticket-template.md
- https://fieldstub.com/extra-work-without-project-financials.md
- https://fieldstub.com/docs/procore-tm-tickets.md
- https://fieldstub.com/subcontractor-extra-work-without-procore.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Data Processing Agreement

> Fieldstub's DPA for customers who need one for GDPR, UK GDPR or CCPA. Covers roles, scope, sub-processors, transfers and breach notification.

Source: https://fieldstub.com/dpa/  ·  Updated 2026-08-09
Effective August 9, 2026

This Data Processing Agreement ("DPA") forms part of the agreement between PurelySearch LLC ("Processor", "we") and the customer ("Controller", "you") for use of Fieldstub (the "Service"). It applies where we process personal data on your behalf and you need a DPA to meet obligations under the GDPR, UK GDPR, CCPA or a similar law. For a countersigned copy, email [privacy@fieldstub.com](mailto:privacy@fieldstub.com).

## 1. Roles

You are the Controller and we are the Processor for all personal data in your Service content. That includes the personal data of your own staff, and, the larger category here, the personal data of people in the field who submit tickets through your capture links.

We process it only to provide the Service and on your documented instructions, which the agreement, your use of the Service, and your configuration choices together constitute. Approving a ticket is an instruction to write that data into your Procore account.

**As Controller you are responsible for** having a lawful basis to collect what your capture codes collect, and for giving the people who submit tickets whatever notice or information the law requires. Those people have no account with us and no channel to us; you are the only party who can reach them.

## 2. Scope of processing

- **Subject matter**: providing the Fieldstub Service.
- **Duration**: the term of your agreement, plus any legally required retention.
- **Nature and purpose**: receiving ticket submissions from your capture links; storing them; presenting them to your reviewers; and, on approval, creating a Change Event with its line items and attachments in your Procore account.
- **Types of personal data**: for your staff: email address and sign-in timestamps. For field submissions: the name and role of the signer, an image of the signature, the name of the person who directed the work, photographs, and per-photo capture time and, where the device provides it, coordinates.
- **Data subjects**: your authorized users; the subcontractors, crew members and other field workers who submit or sign tickets; and any individual appearing in a photograph attached to a ticket.
- **Special categories**: none are requested by the Service. A photograph of a jobsite may incidentally show a person, which is why the sensitivity of what your crews photograph is worth a word in your own notice to them.

## 3. Our obligations

- Process personal data only on your documented instructions.
- Ensure anyone authorized to process it is bound by confidentiality.
- Implement appropriate technical and organizational measures, including encryption in transit and at rest, least-privilege access, and tenant isolation enforced in the service layer. These are described concretely on the [Trust and security](https://fieldstub.com/security/) page, which forms part of this DPA.
- Assist you, taking into account the nature of processing, with data-subject requests and with your security, breach-notification and impact-assessment obligations.
- Notify you without undue delay after becoming aware of a personal-data breach affecting your data.
- On termination, delete or return personal data, except where the law requires us to keep it.

> Change Events already written into your Procore are not ours to delete. They sit in your system under your own agreement with Procore, and our deletion obligation covers the copy we hold.

## 4. Sub-processors

You authorize us to engage the sub-processors below. The current list, with what each one handles, is on the [Trust and security](https://fieldstub.com/security/) page. We will update it and aim to notify you before a new sub-processor handling personal data takes effect, so you can object on reasonable grounds. We remain responsible for their performance.

| Sub-processor | Purpose | Location |
|---|---|---|
| Railway | Application hosting and the Postgres database | United States |
| Resend | Transactional email: sign-in links and notifications | United States |
| PostHog | Product analytics | United States |
| Cloudflare | DNS and inbound email routing | United States |

**Procore is not a sub-processor.** It is your system, held under your agreement with Procore, and our writing to it is the performance of your instruction rather than a disclosure to a vendor of ours.

## 5. International transfers

We and our sub-processors process data in the United States. Where personal data is transferred from the EEA, UK or Switzerland, the parties rely on a lawful transfer mechanism such as the EU Standard Contractual Clauses, incorporated by reference where applicable.

## 6. Audits

On reasonable written request and subject to confidentiality, we will provide the information necessary to demonstrate compliance with this DPA, including answering a security questionnaire.

We hold no third-party audit report or certification today, and we will not imply one. If we obtain a SOC 2 report in future, providing it will satisfy this section.

## 7. Data-subject requests

If a data subject contacts us directly about data we process for you, we will not respond substantively other than to direct them to you, and we will tell you promptly. Where a request concerns a field submission we will help you locate and act on the record.

## 8. Liability and precedence

This DPA is subject to the limitation of liability in our [Terms of Service](https://fieldstub.com/terms/). Where this DPA and the Terms conflict on the processing of personal data, this DPA controls.

## 9. Contact

PurelySearch LLC · [privacy@fieldstub.com](mailto:privacy@fieldstub.com)

## Related

- https://fieldstub.com/security.md
- https://fieldstub.com/privacy.md
- https://fieldstub.com/terms.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Capturing extra work in Procore without Project Financials

> Change Events need Project Financials. Without it a daily log still takes headcount, hours and notes with no budget code. Verified on a live sandbox.

Source: https://fieldstub.com/extra-work-without-project-financials/  ·  Updated 2026-08-30
Probed against a live Procore sandbox on 2026-08-29 and 2026-08-30. Reproduce with gate0/probe-fieldtools.mjs

**[Change Events](https://support.procore.com/products/online/user-guide/project-level/change-events) are part of [Project Financials](https://support.procore.com/products/online/financial-management-user-guides).** If your company did not buy that module, the tool is not on your projects, and every integration that files extra work as a change event, ours included, has nothing to write into.

That is usually where the conversation stops. So we probed a sandbox to find out what a project can actually accept without it, and the answer is more than nothing and less than you want.

**Fieldstub does this now.** On a project with no Change Events tool, approving a ticket files it to the Procore daily log instead. The rest of this page is what that is worth, stated plainly, because it is not the same thing as a Change Event and we would rather you knew that before you bought than after.

## What still works

The [daily log](https://support.procore.com/products/online/user-guide/project-level/daily-log) tools take a record of extra work with **no budget code and nothing financial in the payload at all**. Posted and confirmed:

| Endpoint | Result | What it carries |
|---|---|---|
| `POST /rest/v1.0/projects/{id}/manpower_logs` | **201** | Vendor, number of workers, number of hours, notes |
| `POST /rest/v1.0/projects/{id}/notes_logs` | **201** | Free text against a date |

Readable alongside them: `daily_construction_report_logs` and `work_logs`. The vendor id has to come from the project vendor list at `/rest/v1.0/projects/{id}/vendors`, not the company one.

> Daily logs are **nested** under `/projects/{id}/`, unlike the financial resources which hang off `?project_id=`. The typed logs take a `log_date`; the `daily_logs` container wants `start_date` and `end_date` and returns 400 if you send it `log_date`.

## What Fieldstub does with it

Approving a ticket on a project with no Change Events tool writes a manpower log carrying the description, why the work was out of scope, who directed it, the crew size and hours, an itemised summary of equipment and materials, who signed and when, and a link back to the full record.

The destination is **never chosen for you**. Over the API and over MCP, approving such a ticket returns `409 no_change_events` until you pass `destination: "daily_log"` explicitly. In the review queue the button reads **Approve and file to the daily log**, and the screen says what that means before you press it.

> That is deliberate, and it costs a round trip. A change event is money on a budget code and a daily log bills nothing, so approval cannot be allowed to mean two different things depending on a license the approver cannot see. Read the capability first: `GET /v1/projects/{project_id}/capability`, or the `project_capability` tool over MCP.

Two Procore behaviors we had to design around, both verified:

- **There is no idempotency key on a daily log.** Posting the same log twice creates two rows; Procore does not dedupe. Fieldstub writes a marker into the notes and looks for it before writing, so a retry is not a duplicate.
- **Attachments are silently discarded.** A multipart create or PATCH returns 200 with `attachments: []` and the file is gone. So the photos and the signature image stay in Fieldstub, and the note says where they are rather than implying they came along.

## What it is worth, honestly

**A manpower log is a diary entry, not money.** Nothing bills from it. It does not roll into a change order, it does not touch a budget line, and no one reconciling a job at closeout is going to find it on their own.

So this is not Procore without Financials working the same way. It is:

- **A real destination** for a ticket on a project that cannot take a Change Event, where previously the honest answer was that there was none.
- **The evidence half of the claim.** Signed, timestamped, photographed, filed in the owner's own system on the day it happened. That is the artifact that is missing when a paper ticket does not survive the week.
- **A degraded mode**, and anyone telling you otherwise is selling.

If the money side matters, and it usually does, the answer is Project Financials or a different system of record. There is no clever way around a module you did not buy.

## Timecards: unproven, and not for the reason you would guess

Field Productivity timecards look like the better fit for labour on a T&M ticket, because they carry an employee and hours and can be costed. We could not confirm them.

`POST /rest/v1.0/projects/{id}/timecard_entries` returned `422`:

```
{"errors":"You have assigned an invalid person for your permission level"}
```

A `party_id` variant returned `login_information_id: 9335 not found` and `ancestry does not match`.

**Neither error mentions a cost code**, and that distinction is the whole finding. An error naming a budget field would have meant timecards are gated by Project Financials too. These name the person, which is a service account permission gap and an empty sandbox, and says nothing either way about the money question.

Settling it needs Field Productivity tool permissions on the service account and at least one crew or worker on the project. Both `/crews` and `/timecard_entries` returned empty on ours.

## The thing we cannot tell you

**We do not know what share of Procore customers have Project Financials.** Nobody has published it and we are not going to guess at it here.

It is worth knowing that this constraint is not unique to us. Every one of Procore's own ERP connector listings names Project Financials as a requirement, and so does the marketplace listing for Clearstory, the established product in this category. Whatever the number is, it is the number the whole category works inside.

One consequence worth stating plainly: a general contractor not running Project Financials is probably not managing change events in Procore at all. The extra work is already living in a spreadsheet or an email thread. That may mean the module is qualifying the buyer rather than shrinking the market, but that is a hypothesis and we will say so until somebody answers it properly.

## How to check what you have

Open a project and look for **Change Events** in the tool list. If it is not there, Project Financials is not on that project.

By API, try reading change events for the project:

```
GET /rest/v1.0/change_events?project_id={project_id}
```

A 403 or a 404 where other tools answer normally is the tool being absent rather than a permission problem with your token. Worth confirming against a project you know is configured before concluding anything.

## Questions

### Do Procore Change Events require Project Financials?

Yes. Change Events is part of the Project Financials module. Without it the tool is not available on the project and no integration can write a change event into it.

### Can you record extra work in Procore without Project Financials?

Yes, but not as a cost. Fieldstub files the ticket to the Procore daily log as a manpower log carrying the description, hours, who directed it and who signed. It is a dated record, not a financial one, and nothing bills from it.

### Will a daily log entry turn into a change order?

No. It is a diary entry. It is useful as dated, signed evidence that the work happened, which is what a claim is built from later, but somebody still has to raise the commercial change separately.

### Can Procore timecards be used for T&M labour without Project Financials?

Unconfirmed. Our writes were rejected for the person assigned rather than for any cost or budget field, which points at a service account permission gap rather than a Financials dependency. It needs Field Productivity permissions and a crew on the project to settle.

## Related

- https://fieldstub.com/tm-tickets-in-procore.md
- https://fieldstub.com/docs/procore-budget-codes.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# Procore's T&M Tickets tool: what it does, and what it needs

> Procore ships a T&M Tickets tool for labor, equipment, materials and signatures. It needs a Procore seat and the mobile app, and it has no public REST API.

Source: https://fieldstub.com/docs/procore-tm-tickets/  ·  Updated 2026-08-09
API findings verified against a Procore sandbox, August 2026

Procore has its own tool for this, and a surprising number of people evaluating third party options do not know it exists. It is worth understanding properly before you buy anything, including ours.

The short answer: it is a good tool, and whether it solves your problem comes down to one question. Do the people doing your extra work have Procore?

## What it is

[T&M Tickets](https://support.procore.com/products/online/user-guide/project-level/tm-tickets) is a project tool inside Procore for documenting out-of-scope work. In Procore's own words it modernizes the traditional carbon copy forms used on job sites.

It captures the things a T&M ticket has always captured:

- Labor, with trades and hours
- Equipment
- Materials
- A digital signature, collected on a mobile device

That object model is correct, and it is the same shape any serious tool in this category lands on. It also lines up with Procore's own cost structure, where the WBS cost type segment is natively Equipment, Labor and Materials: the three components of a T&M ticket, with no translation needed.

## What it requires

Two requirements decide most evaluations.

**A Procore seat and the mobile app.** The capture path is Procore itself, so the person filling in the ticket has to be a licensed user, signed in, with the app installed and current.

**No public REST API.** We went looking, because Fieldstub would have written to T&M Tickets if it could. Twelve resource name variants all return 404, including `time_and_materials` taken directly from the tool's own URL in the web app, tried against both the `?project_id=` and nested path conventions across API versions v1.0, v1.1 and v2.0. The tool was enabled and set to Admin on the test project and appears in its tool list, so this is not a permissions gap. Procore also publishes extensive end-user documentation for the tool and no developer documentation at all.

> Verified August 2026 against a Procore developer sandbox. An undocumented internal endpoint could exist, and an API for this tool is an obvious future release. If it ships, the calculus here changes.

## When it is the right answer

Use Procore's tool, without hesitation, when:

- The extra work is done by your own people, and they already carry Procore.
- Your crews are already trained on the mobile app and use it daily.
- You do not need to read those tickets from any other system.

In that situation a third party tool is a second thing to buy and administer for a job Procore already does inside the platform you own.

## When it is not

The gap is not a feature. It is a population.

On most jobs the people who know what actually happened are subcontractors and crew members who do not have Procore, will not be given a seat, and would not be trained on the app if they were. A tool that captures the work of people who already have Procore captures the wrong half of the problem, because that half was mostly getting recorded anyway.

The other half is a foreman in a truck with a carbon copy pad, and that pad is what never makes it back to the office.

|  | Procore T&M Tickets | Fieldstub |
|---|---|---|
| Field needs a Procore seat | Yes | No |
| Field needs an app installed | Yes | No, a phone browser |
| Captures labor, equipment, materials, signature | Yes | Yes |
| Readable by other systems | No public API | Writes a change event, which has one |
| Where the record lands | A T&M ticket | A change event with typed line items on budget codes |
| Office review before anything is filed | Inside Procore | A review queue, and nothing writes unreviewed |

We are not neutral here, so treat the right column accordingly. The left column is checkable against Procore's own documentation, and the API row is reproducible by anyone with a sandbox.

## Questions

### Does Procore have a T&M Tickets API?

Not a public one. Twelve resource name variants return 404 across API versions, on both path conventions, with the tool enabled and set to Admin. Procore publishes no developer documentation for it.

### Can a subcontractor fill in a Procore T&M ticket?

Only if they have a Procore seat and the mobile app. Most subs on most jobs have neither.

### Is Fieldstub a replacement for Procore T&M Tickets?

Only for the work done by people without Procore, which in practice is most extra work. If your own crews already use the Procore app, their tool is the simpler answer.

### Why does Fieldstub write change events instead of T&M tickets?

Two reasons. T&M Tickets is not addressable through any public API, and a change event carries the cost into the budget and on toward a change order and Procore Pay. Change events also stay editable after an integration creates them, which is what makes an office review loop possible.

## Related

- https://fieldstub.com/tm-tickets-in-procore.md
- https://fieldstub.com/docs/procore-change-events-api.md
- https://fieldstub.com/subcontractor-extra-work-without-procore.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# How subcontractors submit extra work without a Procore license

> Subs rarely have a Procore seat, and the tools for extra work assume one. Here is what actually works, and what a GC has to set up for it to work.

Source: https://fieldstub.com/subcontractor-extra-work-without-procore/  ·  Updated 2026-08-09

You did work that was not in your scope. The general contractor uses Procore. You do not have Procore, you are not going to be given a seat, and the ticket is currently a carbon copy in your truck.

This is the most common situation in the category and almost every tool built for it assumes you have an account. Here is what actually happens, and what has to be true for each option to work.

## Why the seat is the whole problem

Procore is licensed by the general contractor or the owner. Their staff have seats. You are on the job for four months, you work for six other GCs this year, and each of them runs a different system.

Even where a GC can invite you, it rarely holds up. Somebody has to create the account, somebody has to train the person who is actually on the tools, and that person changes. The tool works on the days when everyone remembers.

So the honest constraint is this: **anything that requires the person who did the work to log in will not be used consistently.** Not because anyone is being difficult, but because the person holding the information is the least connected person on the job.

## What subs do today

| What | Works? |
|---|---|
| Carbon copy pad, hand a signed copy to the super | Yes, until the copy is lost or the super who signed it leaves |
| Photo of the pad, texted to the PM | Sometimes. It is a photo, so nobody can total it or code it |
| Your own T&M form as a PDF, emailed | Better. Still lands in an inbox, not a budget |
| A seat on the GC's Procore | Rare, and rarely used by the person on the tools |

All four end the same way. The information exists, and it is not anywhere that produces an invoice.

## What actually works

A capture tool where **the link is the credential**. The GC installs it, prints a QR code, and tapes it in the gang box or the trailer. Anyone scans it, fills in a form in a phone browser, adds photos and a signature, and submits. No app, no account, no invitation.

The GC's office reviews what came in and approves it. Only then does anything reach Procore, as a change event with the labor, equipment and materials as typed line items against real budget codes.

That split is the point. You are trusted to describe the work, because you are the one who did it. You are not trusted to write into somebody's financials, and you should not want to be.

![A gloved hand holding a phone in bright direct sunlight on a jobsite. The screen shows the Fieldstub capture form on step one of five, headed "What work happened?", with the answer being dictated: the box is outlined, tagged LISTENING, and reads "Removed an unmarked concrete footing at grid C-4. It was not on the drawings and it was blocking the pile cap." The button at the bottom reads "Listening...". A language switcher in the header offers EN, ES and FR.](https://fieldstub.com/assets/shots/FLD-03.jpg)

The whole of the field side. A browser, in a glove, in the sun. You can talk to it instead of typing, and it will ask the questions in English, Spanish or French.

> This is what Fieldstub does. The field side needs nothing: no app, no login, no Procore seat, ever. It is the GC who installs it and the GC who pays for it.

## What to ask your GC for

You cannot install this yourself. The Procore account is theirs, the change event is theirs, and the license is theirs. What you can do is ask for something specific instead of complaining about paperwork:

- A way to submit extra work that does not need a Procore login, so the person who did the work files it the same day.
- A confirmation that what you submitted was received, so nothing depends on whether a piece of paper survived a truck.
- Line items coded to the budget, so the cost is somewhere reviewable rather than in a folder.

If it helps, send them this page. Their side of it is [the four ways to get T&M tickets into Procore](https://fieldstub.com/tm-tickets-in-procore/), and the honest comparison includes options that are not us.

## What it costs you

Nothing. Fieldstub bills the general contractor per active project, and field users are unlimited on every plan including the free one. There is no per-person pricing, because a tool that charges by the person is a tool that gets rationed to the people who need it least.

## Questions

### Can I submit a T&M ticket to Procore without an account?

Not through Procore directly. Its T&M Tickets tool needs a seat and the mobile app. With a capture tool that the GC installs, you can submit from a phone browser with no account, and it reaches Procore after the office approves it.

### Who pays for it, me or the general contractor?

The GC. They own the Procore account and the change event. Field users are unlimited and free on every plan.

### Can I see what happened to a ticket I submitted?

You get a confirmation when it is submitted. The review and approval happen inside the GC's office, in their Procore, because it is their financial record.

### What if my GC does not use Procore?

Then Fieldstub is not the answer today. It writes into Procore specifically, and there is no version that works without it.

## Related

- https://fieldstub.com/tm-tickets-in-procore.md
- https://fieldstub.com/docs/procore-tm-tickets.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# The Fieldstub API

> Create extra work tickets, read where each line will land, and file them into Procore as change events. REST, API keys, and an OpenAPI spec.

Source: https://fieldstub.com/docs/api/  ·  Updated 2026-08-30

Everything the review queue does, your code can do. Create a ticket, read where each line of money is about to land, and approve it into Procore as a change event with typed line items on real budget codes.

Base URL is `https://app.fieldstub.com/v1`. The full reference is the [OpenAPI spec](https://app.fieldstub.com/v1/openapi.json), which needs no key to read.

## Two things to understand before you build

> **Creating a ticket is safe. Approving one is not.** A ticket is a record of a claim, and nothing about it touches anyone's financials. Approving writes a change event into a customer's Procore and is not reversible from here.

**Check `routing` before you approve.** Every ticket read comes back with a `routing` array saying exactly which budget code each line will hit. Procore accepts a line item with a blank budget code without any warning, which is [how costs quietly go missing](https://fieldstub.com/docs/procore-budget-codes/), so a line we could not confidently route comes back with `needs_review: true` and approve will refuse it.

You can override that with `allow_unrouted: true`. It exists so that accepting a blank code is a decision somebody makes on purpose rather than a default nobody noticed.

## Keys

Create one in the review queue at **/keys**. It is shown once. We store a hash, so nobody at Fieldstub can look it up for you later. If it is lost, revoke it and make another.

A key is scoped to one company and can read and write everything that company has.

```
curl https://app.fieldstub.com/v1/me \
  -H "Authorization: Bearer fs_live_..."
```

`X-API-Key` works too, for when you are writing a shell script in a hurry. Rate limit is 120 requests a minute per key.

## The shape of the thing

| Endpoint | What it does |
|---|---|
| `GET /v1/me` | Which company this key belongs to |
| `GET /v1/projects` | Procore projects on that company |
| `GET /v1/tickets` | List, filter by status or project |
| `POST /v1/tickets` | Create a ticket |
| `GET /v1/tickets/{id}` | One ticket, including `routing` |
| `POST /v1/tickets/{id}/approve` | **Writes a change event to Procore** |
| `POST /v1/tickets/{id}/reject` | Close it without writing |
| `POST /v1/tickets/{id}/photos` | Attach photos before it is approved |
| `GET /v1/links`, `POST /v1/links` | Capture links for the field |
| `GET /v1/projects/{id}/cost-codes` | Search the project cost codes |
| `POST /v1/projects/{id}/budget-codes` | Create a budget code the project lacks |

## A whole ticket, start to finish

Create it:

```
curl -X POST https://app.fieldstub.com/v1/tickets \
  -H "Authorization: Bearer $FIELDSTUB_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "360805",
    "description": "Removed unmarked footing at grid C-4",
    "reason": "Not on the drawings, blocking pile cap",
    "directed_by": "Mike Torres, super",
    "labor": [{ "trade": "Laborer", "workers": 3, "hours": 6, "rate": 68 }],
    "equipment": [{ "description": "Excavator", "hours": 6, "rate": 185 }]
  }'
```

Read back where the money lands:

```
{
  "routing": [
    { "line": 0, "description": "Laborer x3 — 6h", "amount": 1224.00,
      "budget_code": null, "routed": false, "needs_review": true },
    { "line": 1, "description": "Excavator — 6h", "amount": 1110.00,
      "budget_code": "01-000.E", "routed": true, "needs_review": false }
  ]
}
```

Line 0 has nowhere to go, because the project has no budgeted labor code. Approving now would fail, on purpose. Fix it by pointing the line at a code you choose:

```
curl -X POST https://app.fieldstub.com/v1/tickets/$ID/approve \
  -H "Authorization: Bearer $FIELDSTUB_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "routes": { "0": 1870754 } }'
```

The response carries the Procore record, including a link to it. Approving the same ticket twice returns the same change event with `already: true` rather than creating a second one.

## If you are pointing an agent at this

People are going to, so here is the honest guidance rather than a disclaimer.

- **Let it create tickets freely.** That is the safe half, and it is genuinely useful: an assistant that turns a voice note or an email thread into a structured ticket is doing real work.
- **Do not let it approve unattended.** Approving is a financial write into someone else's system. A human should see the amount and the budget codes.
- **Never pass `allow_unrouted` automatically.** It exists specifically to make a person say out loud that a cost is going somewhere nobody reviews.
- **Read the spec first.** [openapi.json](https://app.fieldstub.com/v1/openapi.json) is public and describes every field, including which ones mean money.

An MCP server is coming, and it will be a thin wrapper over these same endpoints rather than a second implementation with its own opinions.

## Where a ticket lands, and why you have to say

Change Events live inside Procore's Project Financials. A project without that module has no Change Events tool, so there is nothing to write a change event into. Ask before you approve:

```
GET /v1/projects/{project_id}/capability

{ "change_events": false, "daily_log": true, "destination": "daily_log" }
```

On a project where `change_events` is false, approving without naming a destination returns `409`:

```
{ "error": { "code": "no_change_events", "message": "This project has no Change Events tool ..." } }
```

Pass the destination to go ahead:

```
POST /v1/tickets/{id}/approve
{ "destination": "daily_log" }
```

> The extra round trip is the point. A change event is money on a budget code; a daily log is a dated record that bills nothing and cannot carry the photos, because Procore silently discards attachments on one. Falling back automatically would make `approve` mean two different things depending on a license the caller cannot see, so we make you say which one you meant.

A written ticket always reports where it went, so nothing has to be inferred from which id happens to be null:

```
"procore": {
  "destination": "daily_log",
  "change_event_id": null,
  "manpower_log_id": 2213053,
  "note": "Filed to the Procore daily log. Not a financial record ..."
}
```

**Every ticket also carries who decided what.** Procore's own audit shows the service account that wrote the change event, because that is what wrote it, so this is the only record of the person or credential that released the money. A key approving through this API is recorded as the key, never as whoever created it.

```
"approved_by": "key:Ops automation (fs_live_8Kd2)",
"approved_at": "2026-09-04T14:22:10.108Z",
"decisions": [
  { "action": "rejected", "by": "pe@acme.com", "at": "2026-09-04T13:40:02.771Z" },
  { "action": "approved", "by": "key:Ops automation (fs_live_8Kd2)", "at": "2026-09-04T14:22:10.108Z" }
]
```

The array is appended to and never rewritten, so a ticket somebody rejected and somebody else approved anyway keeps both entries. That sequence is the one an audit asks about, and a single `approved_by` would erase half of it.

## Errors

Every error has the same shape and a stable `code` you can branch on.

```
{ "error": { "code": "project_not_found", "message": "No project 111111 on this company" } }
```

| Status | When |
|---|---|
| `400` | The ticket is incomplete. `details` lists every problem at once, not just the first |
| `401` | Missing, malformed or revoked key |
| `404` | No such ticket, link or project *on this company*. Cross-tenant reads look identical to things that do not exist |
| `409` | Already written, already rejected, or `no_change_events`: the project has no Project Financials, so name a `destination` |
| `429` | More than 120 requests in a minute |
| `502` | Procore refused the write. The message is theirs and is usually actionable |

## Questions

### Why does approve fail with no_change_events?

The project has no Change Events tool, which means the company does not have Project Financials on it. Read GET /v1/projects/{project_id}/capability, then approve again with destination daily_log to file a dated record instead. It is never chosen automatically because a daily log bills nothing.

### Can I create a ticket without a QR code?

Yes. POST /v1/tickets with a project_id does the same thing the capture form does, with the same validation. The QR link exists for people who have no account; the API exists for systems that do.

### Is approving idempotent?

Yes. Approving an already-written ticket returns the existing change event with already: true. Fieldstub also sets its own origin_id on the Procore record, so a retry finds the existing one rather than duplicating it.

### What happens if a line cannot be routed to a budget code?

Approve refuses. The line comes back with needs_review true and you either supply a route, create the budget code, or pass allow_unrouted to accept the blank code deliberately.

### Is there an MCP server?

Not yet. It is planned as a wrapper over these endpoints, so anything you build against the REST API now keeps working.

### Are there webhooks?

Not yet. Poll GET /v1/tickets?status=submitted for now. Webhooks are the next thing on this API.

## Related

- https://fieldstub.com/docs/procore-change-events-api.md
- https://fieldstub.com/docs/procore-budget-codes.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---

# The Fieldstub MCP server

> Connect an AI assistant to Fieldstub over MCP. Ten tools for capturing extra work and filing it into Procore, with approval deliberately fenced off.

Source: https://fieldstub.com/docs/mcp/  ·  Updated 2026-08-30

Fieldstub speaks the Model Context Protocol, so an assistant can turn a description of what happened on site into a structured ticket, and see exactly where the money would land in Procore before anyone approves it.

Endpoint: `https://app.fieldstub.com/mcp`. Authentication is the same API key as the REST API, sent as a bearer token.

It is listed in the official MCP registry as `com.fieldstub/fieldstub`, so a client that reads the registry can find it without being told the URL.

## Connecting

Create a key at **/keys** in the review queue, then point your client at the endpoint with an `Authorization` header.

In Claude Code that is one line:

```
claude mcp add --transport http fieldstub https://app.fieldstub.com/mcp \
  --header "Authorization: Bearer fs_live_..."
```

Anywhere that takes a config file:

```
{
  "mcpServers": {
    "fieldstub": {
      "url": "https://app.fieldstub.com/mcp",
      "headers": { "Authorization": "Bearer fs_live_..." }
    }
  }
}
```

Streamable HTTP, stateless. No session to establish and nothing to keep alive: one POST, one response. Protocol versions `2025-11-25` and earlier are supported, which is what clients speak today.

> OAuth is not supported yet, so a client that only does the OAuth discovery flow will not connect. Bearer keys work everywhere a custom header can be set. Saying this plainly rather than letting you find out.

## Finding it

The server is published in the official [Model Context Protocol registry](https://registry.modelcontextprotocol.io):

| Field | Value |
|---|---|
| Name | `com.fieldstub/fieldstub` |
| Transport | `streamable-http` |
| URL | `https://app.fieldstub.com/mcp` |

The namespace is verified by domain ownership rather than a username, so `com.fieldstub/*` can only be published by somebody who controls fieldstub.com. The proof is public at [/.well-known/mcp-registry-auth](https://fieldstub.com/.well-known/mcp-registry-auth) if you want to check rather than take our word for it.

> Being in the registry gets an agent the address, not an account. The endpoint needs a bearer key, which needs a Fieldstub account, which needs the general contractor to have installed Fieldstub in their Procore. Discovery and access are separate problems and only one of them is solved by a listing.

## The tools

| Tool | What it does |
|---|---|
| `list_projects` | Procore projects on your company |
| `project_capability` | Whether a project can take a Change Event, or only a daily log. **Read this before approving** |
| `list_tickets` | Tickets, filterable by status and project |
| `get_ticket` | One ticket plus **routing**: where every line will land |
| `create_ticket` | Record extra work. Safe: nothing reaches Procore |
| `approve_ticket` | **Writes to Procore.** Marked destructive. Takes `destination` on a project with no Financials |
| `reject_ticket` | Close a ticket without writing |
| `search_cost_codes` | Find a cost code on a project |
| `create_budget_code` | Create a budget code the project lacks |
| `create_capture_link` | A no-login URL for the field |

## Two destinations, and the agent has to pick

Change Events live inside Procore's Project Financials. On a project without it there is no Change Events tool and no change event to write, so `approve_ticket` fails rather than improvising:

```
no_change_events: This project has no Change Events tool ...
Approve with destination "daily_log" to file the record to the Procore
daily log instead. That is a diary entry: it carries the description,
hours and who signed, it bills nothing, and it cannot carry the photos.
```

Call `project_capability` first on a project you have not seen:

```
{ "change_events": false, "daily_log": true, "destination": "daily_log" }
```

> The error is the design. An agent that silently downgraded a change event to a diary entry would be reporting success for something that files no money, and the person reading the summary would have no way to tell. Making it fail once, loudly, is cheaper than that.

`destination` is an enum of exactly two values and neither is a way around routing. On a project that *does* have Financials, `requireExact` is still on and an unconfirmed line is still refused.

## What we did about the obvious risk

An agent with a tool that writes into someone's construction financials is a bad idea handled carelessly. Four things, all of them enforced by the server rather than requested in a prompt.

**Approval is marked destructive.** `approve_ticket` carries `destructiveHint`, so clients that ask before destructive calls will ask. The reads are marked read-only so they do not.

**There is no way to accept a blank budget code.** The REST API has `allow_unrouted` for the case where somebody knowingly files a cost to the blank code. That parameter **does not exist on the MCP tool**, and passing it does nothing. It lives in the web review queue, where a person makes that call.

**A merely plausible match is refused too.** This is the subtle one. A line with no cost code still resolves to *a* code of the right cost type: real, plausible, and quite possibly wrong. A reviewer sees that flagged on screen and catches it. Nobody is on screen when an agent calls, so over MCP those lines are refused and must be placed explicitly with `routes`.

**Every response carries a `review_url`.** The moment an agent should stop and hand off, it already has the link to send a person to.

> The server tells the model all of this in its instructions before a single tool runs, so the rules arrive with the connection rather than depending on how someone worded a prompt.

## What a good flow looks like

1. Someone describes the extra work, in a message, a voice note, or a thread.
2. The assistant calls `create_ticket`. Nothing has touched Procore.
3. It calls `get_ticket` and reads `routing`.
4. It shows a person the total and the budget code each line will hit.
5. On an explicit yes, it calls `approve_ticket`. If a line is not on a confirmed code, the call is refused and it either supplies `routes` or sends the person to `review_url`.

Steps 1 to 4 are where the value is. Step 5 is the one to be careful with, and it is fine to decide your assistant never does it.

## Why it is a wrapper, not a second product

Every tool is one call into the same service layer the web review queue and the REST API use. There is one implementation of approving a ticket, so the MCP path cannot quietly develop different rules from the screen a project manager uses.

The one deliberate difference is the direction that makes it stricter, never looser: MCP always demands confirmed budget codes.

## Questions

### Which MCP protocol version does it support?

2025-11-25 and earlier. Revision 2026-07-28 removes sessions and the initialize handshake and adds required Mcp-Method and Mcp-Name headers; the server is stateless already, so that upgrade is additive once clients start asking for it.

### Does it support OAuth?

Not yet. Authentication is a bearer API key from /keys, which works with any client that lets you set a header. OAuth 2.1 with protected resource metadata is what the spec wants for remote servers and is on the list.

### Can an agent approve a ticket on its own?

Technically yes, and we would rather it did not. The tool is marked destructive so clients prompt, it refuses any line not on a confirmed budget code, and it cannot accept the blank code at all. Creating and reviewing tickets is the part worth automating.

### What stops one customer's agent seeing another customer's tickets?

The API key resolves to exactly one Procore company and every call is scoped to it. A ticket belonging to another company reads as though it does not exist.

### Is there a stdio version for local use?

No. The server is remote because the data is, and a local process would still need the same key to reach it.

## Related

- https://fieldstub.com/docs/api.md
- https://fieldstub.com/docs/procore-budget-codes.md

---

Fieldstub captures extra construction work from people with no Procore seat and files it into Procore as a Change Event. https://fieldstub.com/

---
