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

# Zapier

> Automate XBuild from thousands of other apps.

## Enable and use the Zapier integration

Zapier connects XBuild to thousands of other apps so work moves between them without anyone re-typing it. A lead that lands in your CRM can open an XBuild project on its own. A proposal that gets signed can update the job in your CRM, post to your team's Slack channel, and add a row to a spreadsheet. Each one is a "Zap" — you build it once and leave it running.

This article covers connecting your XBuild account to Zapier, the triggers and actions XBuild publishes, the project fields you can map into later steps, and how admins see and revoke their team's access.

Zapier is an **integration**, not a [connector](/connectors/overview), and the difference decides where you set it up. A connector is XBuild reaching out to another tool on behalf of a [Location](/features/locations) — you turn those on in **Settings → Connectors**. An integration is another tool reaching into XBuild as one of your team members, so it's authorized from that tool's side. You connect XBuild from inside Zapier, and there's nothing to switch on in XBuild first.

Connecting is for Administrators. Only an Administrator of a Location can use the integration for it, so connect from an Administrator account — a member's connection can't act on any Location. Seeing and revoking your team's connections, in **Settings → Integrations**, is admin-only too.

### 1. Connect XBuild to Zapier

Connections start in Zapier, and each person makes their own.

1. In Zapier, create a Zap and choose **XBuild** as the app for a trigger or action step.
2. Click **Sign in** when Zapier asks for an XBuild account. A window opens on XBuild.
3. The **Connect to XBuild** page shows which account you're signed in as. Click **Continue** to use it, or **Use a different account** to switch.
4. Review what you're granting and approve it. Zapier brings you back to the Zap editor with the connection ready.

If you're signed out of XBuild when the window opens, you'll see **Log in to continue** instead. Log in and XBuild returns you to the same place to finish connecting.

Your connection is labelled with your email address. That's the whole of what it identifies — if several people on your team have connected, the email is how you tell the connections apart in Zapier.

One connection covers **every Location you're an Administrator of**. You don't connect once per Location; each Zap step picks the Location it acts on instead (see below).

### 2. Choose a Location on every step

Every XBuild trigger, action and search opens with a required **Location** dropdown. Set it on each step.

This exists because your connection isn't tied to a Location — it covers all of them. Nothing about the connection itself says which Location a given Zap should act on, so the step says it.

* The dropdown lists only Locations you're an Administrator of.
* If you belong to more than one company, a **Company** dropdown appears above the Location and narrows the list. People in a single company never see it.
* Projects carry their **Location ID** in the output, so a later step can map that value straight into its own **Location** field as a custom value rather than picking from the dropdown again.

Tip: if a step can't see a project you know exists, check its Location first. A project is only visible in the Location it belongs to, and a mismatched Location is the most common reason a Find or Upload step comes back empty.

### 3. Triggers

A trigger starts a Zap. Every XBuild trigger is instant — XBuild tells Zapier the moment something happens, rather than Zapier checking on a schedule.

#### New project

**New Project** fires the moment a project is created in XBuild, however it was created — someone adds it in the app, a Zap creates it, or a connector opens a draft when a report is ordered on an address that has no project yet.

**Source** tells you which of those it was:

| Source | Means |
| - | - |
| `ui` | Someone created it in XBuild, in the app or in chat |
| `public_api` | A Zap created it, through **Create Project** |
| `connector` | A connector opened a draft — an EagleView or HailTrace order on a new address |

**Watch for loops.** If one Zap creates XBuild projects and another triggers on **New Project**, they will feed each other — and if the CRM on the other end also triggers on new records, the cycle can run away. Add a **Filter** step to your **New Project** Zap so it only continues when **Source** is not `public_api`. That breaks the loop while still catching projects created in the app and by connectors.

**New Project** fires for every project, including ones created in the app that don't have a proposal yet. Those arrive with an empty proposals list.

#### The proposal lifecycle

Seven triggers cover the milestones a proposal passes through. Two kinds of work share the first two steps and then diverge — a **client proposal** is retail work you're selling directly to a homeowner, and an **insurance claim** goes to a carrier.

| Trigger | Fires the moment | Applies to |
| - | - | - |
| **Proposal Published** | the proposal becomes a live offer the homeowner can see | Both |
| **Proposal Sent** | XBuild emails the proposal to the homeowner | Both, when the homeowner email is on |
| **Proposal Viewed** | the proposal is first opened | Client proposals only |
| **Proposal Submitted** | the estimate goes to the carrier | Insurance claims only |
| **Proposal Approved** | the carrier approves the estimate | Insurance claims only |
| **Proposal Signed** | the last required signature is added | Client proposals only |
| **Proposal Funded** | the deposit is collected | Client proposals only |

So a retail job usually runs Published → Sent → Viewed → Signed → Funded, and an insurance job runs Published → Sent → Submitted → Approved. Insurance claims aren't signed in XBuild, so they never reach Signed or Funded. Build the Zaps for the track you actually work in.

Each of these can fire again on a later version of the same proposal. A change order sends a signed proposal back to draft and it climbs the ladder a second time — a real second milestone, not a duplicate.

#### What a trigger gives you

Every proposal trigger gives you the event — **Event ID**, **Event Type**, **Project ID**, the proposal's ID, when it happened, and the **From State** / **To State** of the move — plus the project it belongs to, nested underneath with all the fields in section 6.

Three of the proposal triggers also tell you who the moment involved:

| Trigger | Extra fields | Who they name |
| - | - | - |
| **Proposal Sent** | **Recipient Emails**, **Recipients** | The addresses XBuild emailed the proposal to. CC'd addresses aren't included. **Recipient Emails** is one comma-separated line, ready for an email step's To field. |
| **Proposal Viewed** | **Viewer Name**, **Viewer Email**, **Viewer Type** | The person who opened it |
| **Proposal Signed** | **Signed By Name**, **Signed By Email**, **Signed By Type** | The person whose signature completed the proposal. On a proposal with several signers, that's the last one to sign. |

These fields can be empty when XBuild has no one to name. For example, **Signed By** is empty on older proposals that have no signer list. **Email** is empty for a signer who has no email address, such as someone who signed in person, so map the name first.

Every proposal trigger also gives you **Proposal Signers**: everyone on that version of the proposal, with each person's own viewed and signed times. The same list is on the nested project (see section 6).

**New Project** gives you **Event ID**, **Event Type**, **Project ID**, **Created At** and **Source**, plus the same nested project.

Because the whole project comes along, most Zaps don't need a second step to look anything up. The contact, address, proposal values and documents are already there to map.

#### Triggers that stay quiet

Four cases where a Zap saves and tests cleanly, then never fires. Nothing in Zapier flags them, so check these first if a trigger seems dead.

* **Proposal Viewed, Proposal Signed and Proposal Funded never fire for insurance claims.** XBuild doesn't record a "viewed" milestone on that track, and insurance claims aren't signed in XBuild. If you work insurance, use **Proposal Submitted** and **Proposal Approved** instead.
* **Proposal Sent needs XBuild's homeowner email turned on for that proposal.** The trigger sits downstream of that email actually going out, and it's a per-proposal choice. If you share proposals by sending the link yourself, the proposal stays at published and this trigger never fires — use **Proposal Published** instead.
* **Proposal Submitted and Proposal Approved only ever fire for insurance claims**, since a client proposal never goes to a carrier.

One more worth knowing: **Proposal Viewed** marks the moment a proposal is first opened. It isn't a view counter, and it doesn't fire once per person:

* It fires when the first person opens the proposal. Other people opening it afterwards, and repeat views by anyone, don't fire it again.
* After a re-send, it fires again only if the proposal is opened by someone who hadn't opened it yet, such as a co-signer. Someone reopening it doesn't count.
* On a proposal with several signers, once one of them has signed, neither **Proposal Viewed** nor a re-send's **Proposal Sent** fires again for that version.
* Each new version starts fresh, so the first open of a new version fires it.

### 4. Actions

#### Create project

**Create Project** opens a new project in XBuild — the usual way to turn an inbound lead into real work. Every field is optional, because a bare project is a legitimate starting point and XBuild's chat flow collects whatever the source system didn't have.

| Field | What it does |
| - | - |
| **External ID** | The record's ID in the source system, such as a CRM lead ID. Send it and the action becomes safe to retry — running it again with the same ID returns the project already created for that lead instead of a duplicate. It's also what **Find Project** matches on. |
| **Project Name** | The title XBuild shows for the project, up to 200 characters. Leave it blank and XBuild shows the contact's name or the street instead. |
| **Contact Name / Email / Phone** | The homeowner. See below for how XBuild matches these to your existing contacts. |
| **Street / Street 2 / City / State / Zip** | The project address. |
| **Description** | What the work is, in your words, up to 5000 characters. It shows on the project page and the estimator reads it as context. |
| **Files** | Photos and documents to attach — see below. |

Two behaviours worth knowing before you map the fields:

* **An existing contact wins.** XBuild matches **Contact Email** against that Location's [contacts](/platform/contacts), then falls back to **Contact Phone**. A match links the existing contact rather than creating a second copy of the same person, and the project then shows *that* contact's details — which may not be exactly what your Zap sent (anything the contact doesn't have keeps what you sent). The existing contact itself isn't changed. That's deliberate: it keeps one person from splintering into a dozen records. No match creates the contact from what you sent.
* **The address is verified as a whole.** XBuild verifies it when the project is created. An address that can't be resolved is left off the project rather than stored half-parsed, so its address fields come back empty and you can fix them in XBuild. If your source system keeps the address as one string, map it to **Street**.

#### Upload file to project

**Upload File to Project** attaches photos and documents to a project that already exists. Map the **Project ID** from an earlier **Find Project** or **Create Project** step, and pick the same **Location** that step used.

This is the action to use when a trigger fires once per file — a cloud-storage "new file in folder" Zap, say — and the project it belongs to has no External ID to re-create against.

#### How XBuild reports file uploads

Both actions take files the same way. Map attachments or files from an earlier step, such as email attachments or a file from cloud storage, and Zapier passes them to XBuild.

* **Images** land in the project's photos. **PDFs** land in its documents. Those are the only two types XBuild accepts today.
* XBuild downloads the files in the background, so the action reports whether each one was *accepted*, not whether it finished.
* **A failed file doesn't fail the step.** Check **File Results** if you need to know.

| Limit | Size |
| - | - |
| Files per step | 250 |
| Each photo | 50 MB |
| Each document | 100 MB |
| Files per project | 1000 |

**File Results** has one row per file, with a **Status**:

* `pending` — accepted, and XBuild is downloading it now. This is what a successful upload looks like.
* `imported` — XBuild has already downloaded this file's link for the project, so nothing new was added. You'll see it on a retried or duplicated send. XBuild matches on the link, not the file itself: the same file sent from a different link is downloaded again, and re-sending a link XBuild is still downloading, or one that failed before, shows that earlier result instead.
* `failed` — XBuild couldn't take it. **File Result Error** says why:

| Error | Means |
| - | - |
| `url_not_allowed` | The file's address isn't one XBuild will fetch from |
| `url_unreachable` | The file couldn't be downloaded — it may have expired or been removed |
| `unsupported_content_type` | Not an image or a PDF |
| `file_too_large` | Over the per-file limit above |
| `project_file_limit_reached` | The project is at 1000 files |
| `internal_error` | Something went wrong on XBuild's side — contact support if it persists |

### 5. Find a project

**Find Project** looks a project up by its **External ID** — the ID your source system stamped on it when it was created. The match is exact. If nothing matches, the step returns no results rather than failing, which is what lets you branch on it.

**Find Project** also offers a **create it if it doesn't exist yet** checkbox. Tick it and the step becomes find-or-create: Zapier shows **Create Project**'s fields underneath, and the action creates the project only when the search comes back empty. This is usually what you want for an inbound lead. Map the same source record ID into **External ID** in the create fields too, not just the search. The search on its own doesn't prevent duplicates: if two runs for the same lead happen at once, both can find nothing and both create. With **External ID** set on the create, XBuild catches the second one and returns the project the first one made.

### 6. Project fields you can map

Every step that returns a project returns the same shape, so you map the same fields whether they came from a trigger, a search, or **Create Project**.

| Group | Fields |
| - | - |
| Project | **Project ID**, **Location ID**, **External ID**, **Project Name**, **Project URL**, **Created At**, **Updated At** |
| Contact | **Contact ID**, **Contact Name**, **Contact Email**, **Contact Phone** |
| Address | **Street**, **Street 2**, **City**, **State**, **Zip**, **Address (Formatted)** |
| Proposals | **Proposal ID**, **Proposal Type**, **Proposal Version**, **Proposal State**, **Proposal Status**, **Proposal Value**, **Proposal Created At**, **Proposal Updated At** |
| Signers | **Proposal Signer Name**, **Proposal Signer Email**, **Proposal Signer Type**, **Proposal Signer Status**, **Proposal Signer Viewed At**, **Proposal Signer Signed At** |
| Documents | **File ID**, **File Name**, **File Content Type**, **File URL**, **File Kind**, **File Source**, **File Status**, **File Proposal ID**, **File Uploaded At** |
| Claim | **Claim Number**, **Policy Number**, **Date of Loss**, **Type of Loss** |

A few of these behave in ways worth knowing before you build on them:

* **Project Name** is whatever XBuild displays: the project's title if it has one, otherwise the contact's name, otherwise the street. It's never unique — match on **Project ID** or **External ID**, never the name.
* **Contact ID** is the person's entry in your contacts directory, and it's the way to recognise the same homeowner across several projects. It's empty for name-only leads, which have nothing to match on.
* **Updated At** moves whenever anything on the project changes, including background work. It isn't a reliable "something I care about happened" signal — use the triggers for that.
* **Proposals** has one row per version, newest work included. An empty list means nothing has been drafted yet.
* **Signers** lists everyone on each proposal version, in the order they were added. An empty list means the version has no signer list, which is common on older proposals. **Proposal Signer Viewed At** is when *that* person first opened it.
* **Documents** lists the project's documents. Photos aren't included.
* **Claim** is empty on retail work and on jobs that haven't collected claim details yet.

**Proposal State** and **Proposal Status** both describe where a proposal has got to. **State** is the specific milestone; **Status** is the broader phase it sits in.

| State | Status | The proposal has… |
| - | - | - |
| `published` | published | gone live as an offer |
| `sent` | published | been emailed to the homeowner |
| `viewed` | published | been opened by the homeowner (client proposals) |
| `submitted` | published | gone to the carrier (insurance claims) |
| `approved` | published | been approved by the carrier (insurance claims) |
| `signed` | signed | been signed |
| `funded` | funded | had its deposit collected |

A proposal that hasn't been published yet is in `draft`. You may occasionally see other values as a proposal moves between these or after it's invoiced — filter on the ones above, and use the triggers in section 3 rather than watching the field, since a trigger tells you the moment something changes.

**Proposal Signer Type** says which side of the agreement a signer is on. The **Viewer Type** and **Signed By Type** trigger fields use the same values.

| Type | Means |
| - | - |
| `homeowner_signature` | The homeowner |
| `co_signature` | A co-signer on the homeowner's side, such as a spouse |
| `counter_signature` | Your own team's signature on the proposal |

**Proposal Signer Status** is `pending` until that person signs and `signed` after. A `counter_signature` can also be in one of two other states: `awaiting_homeowner` if your team signs last and a homeowner still has to sign, or `pre_authorized` if your team signed when the proposal was created, before it went out.

### 7. Manage who has access

Because each Administrator connects their own account, admins get a single place to see who has: **Settings → Integrations**, under **Automation**. The Zapier card shows how many connections are active on the Location; open it for the detail.

* **Active connections** lists one row per person, with when they last used the integration.
* There's no **Connect** button here. Connections are made from Zapier's side, so this page is for reviewing and revoking them.
* **Revoke access** cuts one person off. Use it when someone leaves the team.

Revoking is broad, so it's worth being precise about what it does. It removes **every** Zapier connection that person has authorized — for this Location and any other Location they'd connected — and any Zaps running on those connections stop working. Other people's connections aren't affected, and the person can reconnect from Zapier at any time, as long as they're still an Administrator.

To remove a single Zap or a single connection instead, the person who owns it can do that from their own Zapier account at [zapier.com/app/assets/connections](https://zapier.com/app/assets/connections).

### 8. Troubleshooting common issues

**I can't connect, or I'm told my account has no Locations to connect.** You need to be an Administrator of at least one active Location. If you're a member rather than an Administrator, ask an Administrator to change your role, or to build the Zap from their own connection.

**I don't see Settings → Integrations.** The page is admin-only. If you're an Administrator and it still isn't there, contact XBuild Support.

**My trigger tests fine but never fires.** Check the cases in section 3 first — **Proposal Viewed**, **Proposal Signed** or **Proposal Funded** on insurance work, **Proposal Sent** without XBuild's homeowner email, and **Proposal Submitted** or **Proposal Approved** on a client proposal. Each of those subscribes cleanly and then stays quiet forever.

**A step fails with "Only administrators of this location can use the API for it."** The person whose connection the Zap uses isn't an Administrator of that step's Location. This can happen if they were changed to a member, or if the step's **Location** is a mapped custom value rather than a dropdown choice. Ask an Administrator to give them the Administrator role, or rebuild the step on an Administrator's connection.

**A Location isn't in the dropdown.** You only see active Locations you're an Administrator of. Ask an Administrator to check your role.

**A Find or Upload step can't see a project that definitely exists.** Its **Location** is almost certainly wrong. A project is only visible in its own Location, so the step has to name the same one the project lives in — map **Location ID** from the earlier step rather than picking again.

**Create Project made a duplicate.** The action only recognises a repeat when you send an **External ID**. Map your source system's record ID into that field and retries will return the existing project instead of a new one.

**The contact on the project isn't what my Zap sent.** XBuild matched the email or phone to a contact you already had and linked that person instead of creating a second copy. The saved contact's details win wherever it has them, and anything it's missing is filled in from what your Zap sent. Your Zap never changes the saved contact — edit it in XBuild if it's out of date.

**The project has no address.** XBuild verifies the whole address when the project is created, and leaves off one it can't resolve rather than storing something half-correct. Check what your Zap is sending, and fix the address on the project in XBuild.

**My Zaps are creating projects in a loop.** A Zap that creates projects and a Zap that triggers on **New Project** will feed each other. Add a **Filter** step so the **New Project** Zap only continues when **Source** is not `public_api`.

**A file didn't arrive.** Check **File Results** on the step — a failed file doesn't fail the step, so the Zap still shows as successful. **File Result Error** says why. Note that XBuild only accepts images and PDFs.

**Files show as `pending` and I'm not sure they worked.** That's the expected result. XBuild accepted the file and is downloading it in the background — `pending` means success at that point, not a problem. Check the project in XBuild to confirm it landed.

**A Zap stopped working after someone left or changed role.** Revoking a person's access in **Settings → Integrations**, removing them from the Location, or changing their role from Administrator to member all stop every Zap built on their connection. Zaps that should keep running need to be rebuilt on a connection owned by an Administrator who is still on the team.

For help building or troubleshooting Zaps, see [Zapier's help centre](https://help.zapier.com). For XBuild-side issues, contact XBuild Support at [support@x.build](mailto:support@x.build).


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