23 Sep 2026

BuildingConnected API Enhancements: Bid Leveling Controls, Private Attachments, and Bid Package Organizational Attributes

Default blog image

We’re excited to announce the third-round enhancements of year 2026 to BuildingConnected API. This release covers several areas: bid leveling (line item toggle states, and plugs carried forward from a previous revision), private bid attachments, new V3 endpoints for bid attachment and project NDA downloads, bid package organizational attributes, batch retrieval for bid packages and projects, AI bid extraction opt-in on projects, and invite search and filtering. The full list of updates is available in the BuildingConnected change log. 

All of the enhancements in this release are additive. However, the introduction of the new V3 attachment download endpoints means that the corresponding V2 endpoints will be deprecated.

The Transitioning to the New Version API section below provides more details. 

In addition, a separate set of operations is also being deprecated as part of this release. For more information, see our companion post, BuildingConnected API Deprecations(Coming Soon), for details.

Transitioning to the New Version API 

The new V3 endpoints for downloading bid attachments and project NDA attachments include enhanced handling for quarantined attachments.

GET bids/{bidId}/attachments/{attachmentId} (V3) : In V3, signedUrl can now be null. Integrations should check fileStatus before using signedUrl. The V2 endpoint remains unchanged and will be deprecated.

GET projects/{projectId}/nda (V3) : The same handling applies to project NDA attachments. Integrations should check fileStatus before using signedUrl.The V2 endpoint will also be deprecated. 

Migrating from V2 to V3 

The migration effort should be minimal. Update your integration to check fileStatus before using signedUrl and handle QUARANTINED as an attachment state rather than as a failed request. 

Note: There is currently no API endpoint for deleting an active or attached project NDA. As a result, a quarantined NDA cannot be removed or replaced through the API. If your integration identifies a quarantined NDA, flag it for manual processing. 

Bid Leveling 

This release covers two gaps which were not available before:  choosing which alternate and additional item line items take part in a comparison  and carrying leveling work from one bid revision to the next. 

Line Item Toggle States API 

Every alternate and additional item line item starts with a default state in bid leveling. Alternate line items are off, and additional item line items are on. You can override either one to set a specific line item explicitly on or off. Until now the API could not read or set those overrides, so your integration could not see how a leveling sheet was put together, let alone change it. 

Both endpoints return only the values that differ from the defaults, so given a response with three entries, it means three overrides and not three line items in total. If you set an alternate line item’s toggleState to false, it goes back to its default and its lineItemFingerprint entry drops out of the PATCH response and out of later GET responses, so read a missing entry as “default” rather than as an error. 

Apply Previous Plugs API 

When a bidder sends a new revision, the plugs, highlights, and notes an estimator already entered stay with the earlier bid, and there was no API call to apply them again. One call now copies plugs, highlights, and notes onto a bid from an earlier revision by the same bidder. 

This call replaces all plugs, highlights, and notes on the target bid instead of merging into them, so anything already entered on the current revision is overwritten. Make the call when the revision arrives, before anyone starts new leveling work on it. 

Together, these three endpoints handle the setup each new revision needs: read the current overrides with GET bid-packages/{bidPackageId}/line-item-toggle-states, set the ones your comparison needs with PATCH, then copy the earlier revision’s leveling forward with POST bids/{bidId}/apply-previous-plugs.  

Bids

A bid represents more than just the numerical values submitted by a bidder. It also carries associated files, some of which are intended exclusively for the project owner. We previously had gaps covering two key areas: there was no API to access files restricted from bidder view, and integrations could not distinguish a quarantined file from a failed request when downloading attachments. This release resolves both limitations. 

Private Attachments API 

Private attachments are files attached to a bid that only project owners can see; the bidder who sent the bid cannot see them. What the API stores is the link between an attachment and a bidder group, not a copy of the file, so the same file can be linked and unlinked without being deleted. You pass a bidId, and the API looks up the bidder group, which is the invite, for you. Until now the API gave you no way to create those links, remove them, or list the private attachments already on a bid. 

  • GET bids (set the optional includePrivateAttachments boolean to true to add a privateAttachments field to each bid) 

Note: DELETE removes only the link between the attachment and the bidder group. It does not delete the file, so you can link it again. includePrivateAttachments needs write access to the project. If your integration only has read access, leave the parameter out. These four calls now cover the whole life of a private attachment on a bid: link it with POST bids/{bidId}/private-attachments, read it back with includePrivateAttachments on either bid endpoint, and unlink it with DELETE bids/{bidId}/private-attachments/{attachmentId}.

Bid Attachments API (V3)

This has been introduced in Transitioning to the New Version API 

BidPackages 

Bid packages gain two independent new capabilities. The first aligns a package with the same classification and location structure already used elsewhere in the project, enabling consistent filing and discovery. The second addresses scale: previously, retrieving a known set of packages required one separate request for every individual package. 

Bid Package Organizational Attributes API 

A bid package organizational attribute maps a bid package to nodes on a classification tree or a location tree in Forma Preconstruction, which gives the package the same structure the rest of the project uses. One bid package can hold up to 5 classification mappings and 1 location mapping. These mappings had no place in the API at all, so an integration that created a bid package could not classify it or put it on a location tree, and could not read the mappings a package already carried. This release adds every operation. 

Note: The node type mapped during attribute creation cannot be switched to another node type via Patch requests. Attempting to assign a node belonging to a different tree type will return a 400 Bad Request. This restriction applies even when the attributes share the same treeId. You must create a new attribute instead. 

Note: PATCH updates only the nodeIds and includeSubItems you send rather than replacing the whole resource, so any field you leave out keeps its current value and you can send just the one you mean to change.

Bid Packages Batch Get API 

This endpoint supports subcontractor capacity intelligence work in TradeTapp, which looks up large sets of bid packages by ID. To fetch a known set of bid packages, you had to call the single-resource endpoint once per ID, so the number of requests grew with the size of the set. One call now takes a list of bid package IDs and returns the matching records. 

Projects

Three additions land on the project resource: 

AI Bid Extraction Flag 

AI proposal extraction is turned on per project, and the API did not show that setting anywhere, so your integration could not report which projects were opted in and could not opt in a project it created. The aiProposalExtraction field is now accepted in the request or response payload of the endpoints below. You can set the opt-in when you create a project, change it later, and read it back. 

Projects Batch Get API 

Projects needed the same treatment as bid packages for the subcontractor capacity intelligence work described above: one request per project ID does not scale when an integration has to resolve a long list. One call now takes a list of project IDs and returns the matching records. 

Project NDA API (V3) 

This has been introduced in Transitioning to the New Version API 

Invites

Invites could be filtered with filter[updatedAt], but there was no filter for when an invite was created, and no way to narrow a list by name at all, so your integration had to page through invites and match names in its own code. Both are now query parameters on the List Invites endpoint, which also supports the subcontractor capacity intelligence work in TradeTapp. 

  • GET invites (searchText searches projectName and bidPackageName; filter[createdAt] works the way filter[updatedAt] already does, but on the creation timestamp) 

Note: searchText ignores case and matches from the start of a word, and characters such as hyphens count as word separators, so searching const matches a bid package named Pre-Construction. An empty searchText returns all invites rather than none, so treat a blank search box as “no filter” in your own code. 

Two invite endpoints are deprecated in this release. See our companion post, BuildingConnected API Deprecations(Coming Soon), for details. 

Documentation 

If you have questions or feedback about any of these changes, please get in touch with us through the APS support channel.

Related Article