Help Guide

B2W API Help · Ops API

B2W Ops API Help Guide

How to reach your Ops API, get the right credentials, generate a bearer token in Postman, make your first calls, and solve problems when a call fails. Paste your Ops URL into the card to fill in every example.

Part 1

Understand the basics

What the Ops API is, what every call is made of, and how to find your environment’s API and its documentation.

1

What is the B2W Ops API?#

Short answer

The Ops API is how other software reads and writes B2W Ops data, such as jobs, employees, and equipment, without anyone opening an Ops screen. It is a REST API that sends and receives JSON, and every B2W environment has its own.

An API (application programming interface) is a published way for programs, not people, to ask another system to do something over a network. Think of it as three parts of the same building:

Ops database The filing cabinet

Stores the raw data and permanent records behind the scenes.

Ops website The front desk

Screens that people use to find and change records.

Ops API The service window

A written menu that outside software uses to request records.

Companies use it to bring data in from ERP systems, pull data out for reporting dashboards, connect field telematics, and automate repeatable tasks. B2W uses the same API internally for native job imports and true-up batches.

The API never goes around Ops security

It enforces the same security permissions and database validation rules as the application. Nothing bypasses them to write to the database directly, so Ops stays the system of record.

What can you do with it?

Anything you can do in the application, for the functional areas the API exposes, within the permissions of whoever signed in. The version 26.1.2.1 catalog lists 63 functional areas and 272 operations (see question 16).

Ops API vs. legacy Web Services

Some integrations still use the older SOAP Web Services. They are a different product, so check which one you are working with first.

Ops API 2.0 (REST)Legacy Web Services (SOAP)
AddressOne URL per resource, such as /Employee.asmx service URLs
MethodsGET POST PUT DELETEPOST for every call
Data formatJSONXML envelopes, with the operation name inside
QueryingOData: $filter, $select, $orderby, $top, $skipParameters inside the XML
Page sizeUp to 100 records per GETNot applicable
Use the Ops API for new work

Use the Ops API wherever you can. In one example, adding 10 employee records took 10 separate SOAP calls, while the Ops API handled the same work in one call.

2

What makes up an API call?#

Short answer

Every call has an address (the URL), a method (GET, POST, PUT, or DELETE), headers (including who you are), and for create and update calls, a JSON body. Every response comes back with a status code and, usually, JSON data.

PartWhat it doesExample
1. AddressWhere the request goes: your environment’s server and the resourcehttps://<cluster>.b2w.trimble.com/OpsAPI_<environment>/Employee
2. MethodThe action to takeGET read · POST create · PUT update · DELETE remove
3. HeadersExtra instructions, including who is callingAuthorization: Bearer <token>
Content-Type: application/json
4. BodyThe data you send, as JSON, when you create or update{ "LastName": "Newman", … }

The four methods map to the four basic data actions, often called CRUD: Create (POST), Read (GET), Update (PUT), and Delete (DELETE). Here is a complete create call with every part labeled:

HTTP request · create an employee
POST /OpsAPI_<environment>/Employee HTTP/1.1          # 1 address + 2 method
Host: <cluster>.b2w.trimble.com
Authorization: Bearer <AccessToken>                    # 3 headers
Content-Type: application/json

{                                                      # 4 body
  "EmployeeID": "90001",
  "LastName": "Employee",
  "BusinessUnitUniqueName": "Organization"
}

The response always carries a status code, such as 201 Created or 401 Unauthorized, and plain text shaped as JSON. You will see the same responses in Postman, in Swagger, and in integration logs. Question 20 explains every code.

3

How do I find my Ops API URL?#

Short answer

Every cloud API URL follows one formula: https://{cluster}/OpsAPI_{environment}. Take your Ops site address and put OpsAPI_ in front of the environment name. For <environment>, that gives https://<cluster>.b2w.trimble.com/OpsAPI_<environment>.

  • The cluster is the server group your environment is hosted on, such as <cluster>.b2w.trimble.com.
  • The environment is your site name: the last part of your Ops address.
  • Your Ops website is https://{cluster}/{environment}. Your API is the same address with OpsAPI_ added before the environment.
  • The path is not case-sensitive. opsapi_<environment> works the same as OpsAPI_<environment>.
For <environment>Address
Ops websitehttps://<cluster>.b2w.trimble.com/<environment>
Ops API (base URL)https://<cluster>.b2w.trimble.com/OpsAPI_<environment>
API docs (Swagger)https://<cluster>.b2w.trimble.com/OpsAPI_<environment>/doc/index.html
Don’t mix up the APIs

EstAPI_ (Estimate API) and MRAPI_ (Management Reporting API) addresses are different APIs with their own credentials. Each has its own guide; switch to it at the top of the page.

Check an environment

Paste your Ops address. The checker builds all three API addresses and sends a sample request to each one to see whether it answers.

A typo answers with a 404 page

If the environment name is wrong, the server still responds, but with an HTML “404” error page instead of a result. If /Ping/hello returns that page, recheck the spelling and the OpsAPI_ prefix.

4

Where is the API documentation?#

Short answer

Add /doc/index.html to the end of the Ops API URL. Each environment hosts its own Swagger catalog listing every endpoint, the fields it accepts, and the codes it returns.

https://<cluster>.b2w.trimble.com/OpsAPI_<environment>/doc/index.htmlOpen
Figure 1. The top of an Ops API catalog. Click Configuration or Usage Guidelines to expand them. Usage Guidelines explains the login options in B2W’s own words.

Scroll down to API Documentation to see every functional area. Click an area to expand its operations, then click an operation to see its parameters, example values, and response codes.

Figure 2. ① Each functional area expands into its operations. ② Each row is one operation. Employee has DELETE, GET, POST, PUT, and a /schema call.
Good habits
  • Always check Swagger for accurate field lists and the current schema. It reflects that environment’s version.
  • Not sure the API is up? Open its Swagger page first. If the page loads, the API is answering.

The same catalog is also available as a machine-readable OpenAPI 3 file at /doc/v2/OpsAPI.json. Postman can import it to generate requests, but the B2W Ops API collection in question 6 already has authentication set up, so start there.

Part 2

Get set up

Install Postman, import the B2W Ops API collection, pick a login method, and find the credentials it needs.

5

How do I install Postman?#

Short answer

Download the free Postman desktop app from postman.com/downloads, install it, and sign in.

  1. Download the appGo to postman.com/downloads and download the version for your computer (Windows, macOS, or Linux).
  2. Install itRun the installer. Postman opens when it finishes.
  3. Sign inSign in, or create a free account. You need to be signed in to import and save collections.

Download Postman

Postman is one tool among several

Postman sends requests and shows responses in a friendly window. Anything you do in it, you can also do from PowerShell or cURL. Where it helps, this guide shows all three.

6

How do I import the Postman collection?#

Short answer

Download the B2W Ops API collection (a JSON file), then import it into Postman with Ctrl+O. It appears as B2W Ops API in your sidebar, with a request for every area of the API.

  1. Download the collectionClick Download the Postman collection. The file is B2W-Ops-API.postman_collection.json.
  2. Open Import in PostmanClick Import at the top of the sidebar, or press Ctrl+O (⌘+O on a Mac).
  3. Add the fileDrag the downloaded file into the Import window, or click to browse for it.
  4. ConfirmFinish the import. B2W Ops API appears under Collections.

Download the Postman collection

What’s inside

  • B2W Ops API · collection variables live here
    • Auth · the four ways to log in
      • GETLogin with user name and password
      • GETLogin with client ID and secret
      • GETLogin with TID uuid and API secret · recommended
      • GETLoginWithTID
    • Service
    • BusinessUnit, Category, Contact, Employee, Equipment, Job … · one folder per functional area
“Auth” is a folder, not an endpoint

It only groups the login requests. Each one calls GET /Login (or GET /LoginWithTID) with a different pair of credential headers.

7

Which login method should I use?#

Short answer

Use a TID UUID and User API Secret when calls should act as a specific person. That keeps an audit trail and follows their security role. Use a client ID and client secret for unattended integrations, which run as the built-in System Administrator. Username and password still work but are being retired.

Every call except /Ping and /Version needs proof of identity. You prove it once, by sending credentials to the login endpoint in HTTP headers, never in the URL or the JSON body. The response gives you an access token to use on every other call.

MethodHeaders to sendCalls run asUse it for
TID UUID + User API Secret
Recommended
tiduuid
apiSecret
That specific Ops user, limited by their security role People testing the API, and integrations that need an audit trail of who changed what
Client ID + client secret clientId
clientSecret
The built-in System Administrator (elevated access) Unattended integrations, such as scheduled overnight imports and middleware
Username + password
Being retired
userName
password
That Windows / Ops user Older integrations. Plan to move them to TID or client credentials.
LoginWithTID
Separate endpoint
A Trimble ID access token as the bearer token The Ops user linked to that Trimble ID Apps where the person already signed in with Trimble ID
Client ID + secret vs. TID

A client ID and secret give system-administrator-level access. TID keeps an audit trail of what was changed and takes on the persona of the user, following the limits set in their security role.

The order /Login checks headers in

GET /Login looks for one complete pair of credentials, in this order, and uses the first pair it finds:

Priority 1 · User
  • userName
  • password
Priority 2 · Client
  • clientId
  • clientSecret
Priority 3 · API
  • tiduuid
  • apiSecret
If no valid pair is in the headers, GET /Login returns 400 with {"Error":"Authentication information must be specified in the request header"}. That is the exact response the API gives.

Username and password details

The userName header must match the Windows account name stored on the Ops user, written as DOMAIN\user or user@domain. Ops checks the format, verifies the password with the Windows domain controller, then confirms the account exists in the Ops user table. The token it issues is tied to that person, so every action is traceable to them.

LoginWithTID

This is a different endpoint, GET /LoginWithTID. Instead of a credential pair, you send a Trimble ID access token that the person got by signing in to Trimble ID. Ops exchanges it for an Ops access token.

LoginWithTID returns 404? Fix the link, not the password.

A 404 here means Trimble accepted the person, but no Ops user matches their Trimble ID or mobile email address. Fix the Ops user record (its TID / Mobile E-mail Address). Do not reset the password; the Trimble sign-in is already valid.

Trimble Identity (TID) mode

Client ID/secret and Trimble ID logins work when the site runs in Trimble Identity mode. To check a site, open /SystemInfo. A site in Trimble Identity mode returns "IsTIDEnabled": true.

No login method bypasses API security

Whichever way you sign in, every call is still checked against the API permissions and Ops validation rules.

8

How do I find my TID UUID and User API Secret?#

Short answer

In B2W Ops, open your user record and click User API Secret. The dialog shows your TID ID, which is the tiduuid, and your User API Secret, which is the apiSecret.

  1. Open UsersFrom the gear (⚙) menu at the top right of B2W Ops, open Users, then open the person’s record. You land on User View.
  2. Check the TID / Mobile E-mail AddressIt must be filled in. This is what links the Ops user to their Trimble ID.
  3. Click User API SecretIt sits under the e-mail address, between Show TID ID and Manage TID.
  4. Note the security roleCalls made with these credentials can only do what this role allows.
Figure 3. The User View page. The numbers match the steps above.

The User API Secret dialog opens:

  1. TID IDThis is the tiduuid. Put it in the tidUuid variable in Postman.
  2. User API SecretThis is the apiSecret. Put it in the apiSecret variable.
  3. Copy to ClipboardCopies the secret, which is masked on screen.
  4. Generate User API SecretCreates a secret when the user doesn’t have one. A value must be generated before anyone can call the API as this user.
Figure 4. The User API Secret dialog. The TID ID is hidden in this guide.
Treat “Generate” as a reset

If an integration already uses this user’s secret, coordinate with its owner before generating a new one.

Same values, different spellings

You may see this pair written as “tidUID and apiSecret”. In the login headers they are tiduuid and apiSecret. In the Postman collection they are the tidUuid and apiSecret variables.

9

How do I find my clientID and clientSecret?#

Short answer

In B2W Ops, go to Integrations & Add-ins and click Manage API Key. That dialog holds the client ID and client secret for the environment.

  1. Open Integrations & Add-insFrom the gear (⚙) menu at the top right of B2W Ops, open Integrations & Add-ins.
  2. Click Manage API KeyIt is the first button at the top right of the page. The dialog shows the client ID and client secret that B2W Ops generated for this environment.
  3. Use them in PostmanPut them in the clientId and clientSecret variables, then send Auth → Login with client ID and secret.
Figure 5. ① The Integrations & Add-ins page. ② Manage API Key. The middle of the page is trimmed to save space.
Never send a client ID and secret over email

These credentials log in as the built-in System Administrator, with full access to your data. Share them only through a secure channel, and only with people who need them.

Don’t replace a key that is in use

Ops validates logins against the key stored in its settings. If a new key is generated, integrations still using the old secret start failing with 401 until they are updated.

When to use it: scheduled overnight jobs and middleware that shouldn’t depend on one person’s credentials. Two responses are specific to this method:

  • 401 The client ID or secret doesn’t match the values stored in Ops system settings.
  • 404 The credentials are valid, but the built-in System Administrator record is missing in Ops.
10

How do I fill out the Postman variables?#

Short answer

Click the B2W Ops API collection itself (the top level), open the Variables tab, and fill in baseUrl plus the credential pair you are using. Save with Ctrl+S.

  1. Open the collection’s Variables tabIn the sidebar, click B2W Ops API at the very top, then the Variables tab.
  2. baseUrlThe Ops API URL with no slash at the end, for example https://<cluster>.b2w.trimble.com/OpsAPI_<environment>.
  3. tidUuidThe TID ID from the User API Secret dialog.
  4. apiSecretThe User API Secret.
  5. accessTokenLeave it. It holds your token after you log in (question 11).
Figure 6. The collection’s Variables tab. The address is blurred, and the TID ID and secret are hidden.
VariableWhat goes in itExample or default
baseUrlYour Ops API URLhttps://<cluster>.b2w.trimble.com/OpsAPI_<environment>
accessTokenThe AccessToken from the login responseFilled in after you log in
tidUuid · apiSecretTID ID and User API Secret (question 8)Your own values
clientId · clientSecretFrom Manage API Key (question 9)The environment’s values
userName · passwordWindows account credentials (being retired)DOMAIN\user
trimbleTokenA Trimble ID access token, for LoginWithTIDOptional
objectIdThe ObjectID of a record to update or deletea4066d42-4027-4d5d-87a0-a30600f8d4cf
pageSizeRecords per page100
pingInputText that /Ping echoes backhello
trueUpBatchNumber · categoryType · jobNumber · maintenanceRequestIdInputs for specific requests in those foldersAs needed
Treat secrets like passwords

Don’t share or export the collection while apiSecret, clientSecret, password, or accessToken hold real values. Clear them first.

Part 3

Make calls

Get a token, use it, check connectivity, query data, and make changes safely.

11

How do I generate a Bearer Token?#

Short answer

Send GET {baseUrl}/Login with your credentials in the headers. The AccessToken in the JSON response is your bearer token. In Postman: Auth → Login with TID uuid and API secret → Send.

  1. Open the Auth folderIn the B2W Ops API collection.
  2. Select “Login with TID uuid and API secret”It is a GET request to {{baseUrl}}/Login.
  3. Check the headersOn the Headers tab, tiduuid and apiSecret pull their values from your variables.
  4. Click SendOr press Ctrl+Enter.
  5. Look for 200 OKAny other code means the login failed. See question 21.
  6. Find the AccessTokenThat value is your bearer token. Make sure it is in the accessToken variable before you call other endpoints.
Figure 7. Generating a token. The numbers match the steps above. The token values are hidden.

The same request outside Postman

Postman
GET{{baseUrl}}/Login

Headers

tiduuid

{{tidUuid}}

apiSecret

{{apiSecret}}

Body

none

Login never takes a body.

A successful login returns 200 OK and a small JSON object:

Response · 200 OK
{
  "AccessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi…",
  "RefreshToken": "<refresh token>"
}

Token facts

  • AccessToken and bearer token mean the same thing. It is a signed JWT.
  • A token lasts 1 day by default. The site setting Security:JWT:Lifetime controls this.
  • A token also stops working once you generate a new one, so always use your latest.
  • When a token expires, data calls return 401 Unauthorized. Log in again for a new one.
  • The response also includes a RefreshToken. The catalog has no refresh endpoint, so when your token expires, simply log in again.

Is a token expired, or whose is it? Paste it into the . It shows when the token was issued and expires, and who it belongs to. It decodes the token on this page only and clears it when you close the window.

A token is a password for a day

Anyone holding it can act as you until it expires. Don’t paste tokens into emails, chats, support cases, or screenshots.

12

How do I use the token on a data call?#

Short answer

Send it in the Authorization header as the word Bearer, one space, then the token. Add Content-Type: application/json when the call has a body.

Signing in and calling data are separate steps. Your secrets only ever go to the login endpoint; every other call carries the token instead. Here is a first data call that reads five employees:

Postman
GET{{baseUrl}}/Employee?$top=5

Authorization

Type

Bearer Token, inherited from the collection

Token

{{accessToken}}

The response is a JSON array of employee records. This sample comes from the catalog’s own example:

Response · 200 OK (shortened)
[
  {
    "ObjectID": "a4066d42-4027-4d5d-87a0-a30600f8d4cf",
    "EmployeeID": "12865",
    "FirstName": "Ralph",
    "LastName": "Newman",
    "JobTitle": "Field Employee",
    "IsFieldEmployee": true,
    "IsInactive": false,
    "BusinessUnitUniqueName": "Northern Division\\Paving",
    "RowVersion": 1
  }
]
In the collection, auth is already wired up

The collection’s Authorization tab sends {{accessToken}} as a bearer token, and its requests inherit that setting. If a call returns 401 right after you logged in, check that accessToken holds your newest token and that the request’s Authorization tab is set to inherit from its parent.

Get the header exactly right

Authorization: Bearer eyJhbGciOi… uses the word Bearer, a single space, and the token with no quotes around it.

13

How do I check connectivity without logging in?#

Short answer

Open {baseUrl}/Ping/hello in a browser. If you get the server name back, the API is reachable. /Version returns the API version. Neither one needs a login.

CallExample response (version 26.1.2.1)What it tells youOpen
GET /Ping/hello(server-name) hello|The site is up. It echoes your text with the name of the server that answered.Open
GET /Version26.1.2.1The Ops API build the environment is running.Open
GET /SystemInfo{"IsTIDEnabled":true,"IsEMSLicensed":false}Whether the site runs in Trimble Identity mode. In version 26.1.2.1 it also answered without a login.Open

Reading the result

You seeIt means
The server name and your textThe site and network are healthy. Move on to the login.
A timeout or “connection refused”The API site, the IIS web server, or the network is down. Check connectivity, routing, and the IIS host.
An HTML “404” pageThe server is up but that address doesn’t exist. Check the environment name and the OpsAPI_ prefix.
401 on /Employee or /Employee/schemaExpected without a token. Every data call, including /schema, needs one.

In the Postman collection, the Ping request uses the pingInput variable, which defaults to hello.

14

How do I filter, sort, and page through results?#

Short answer

GET endpoints accept OData query options: $filter, $select, $orderby, $top, and $skip. Each call returns at most 100 records, so use $skip to fetch the next page.

OptionWhat it doesExample from the catalog
$filterReturns only matching records$filter=EmployeeID eq '12865'
$selectReturns only the fields you list$select=EmployeeID
$orderbySorts the results$orderby=EmployeeID, LastName, FirstName asc
$topLimits how many records come back (100 at most)$top=1
$skipSkips records, for paging$skip=1
Figure 8. Every GET operation in Swagger lists the OData options it accepts. They can be combined into one query.

Examples for <environment>

Postman URLs
# One employee by ID
{{baseUrl}}/Employee?$filter=EmployeeID eq '12865'

# Just three fields, sorted by last name
{{baseUrl}}/Employee?$select=EmployeeID,FirstName,LastName&$orderby=LastName

# Active jobs, page 2 (records 101-200)
{{baseUrl}}/Job?$filter=IsActive eq true&$orderby=JobNumber&$top=100&$skip=100

Paging through more than 100 records

PageAdd to the URLRecords
1$top=100&$skip=01–100
2$top=100&$skip=100101–200
3$top=100&$skip=200201–300

Keep going until a page comes back with fewer than 100 records. Sort with $orderby so the pages stay in a stable order.

Exactly 100 rows usually means “more to come”

A GET that returns exactly 100 records has hit the page size, not the end of the data. Ask for the next page before assuming records are missing.

OData syntax tips
  • Put text values in single quotes: LastName eq 'Newman'.
  • Compare with eq, ne, gt, ge, lt, and le. Combine conditions with and and or.
  • Join options with &. Postman and browsers encode the spaces for you.
  • Not sure of a field name or how to write a date? The in the request builder lists each endpoint’s fields and writes the $filter for you.
15

How do I create, update, or delete a record?#

Short answer

POST creates, PUT updates, and DELETE removes. Before you write anything, GET a record from the same area so you can copy its exact shape.

Try write calls in a test environment first

Write calls change real data. If you have a test or sandbox environment, try them there first, and never run them against someone else’s environment unless they asked for the change.

Create a record (POST)

Send the new record as JSON. For an employee, the catalog requires EmployeeID, LastName, and BusinessUnitUniqueName. A success returns 201 Created; a body that isn’t a valid record returns 422.

Postman
POST{{baseUrl}}/Employee

Body · raw · JSON

EmployeeID

"90001"

FirstName

"Test"

LastName

"Employee"

BusinessUnitUniqueName

"Organization"

IsFieldEmployee

true

Update a record (PUT)

The catalog’s rule: first GET the record by its key, change the fields you need, then PUT the whole record back. Keep its ObjectID and RowVersion exactly as you received them. A success returns 200 OK.

PowerShell · get, change, put
# 1. GET the current record
$record = Invoke-RestMethod -Uri "$baseUrl/Employee" -Headers $headers -Body @{ '$filter' = "EmployeeID eq '90001'" } | Select-Object -First 1

# 2. Change only what you need
$record.JobTitle = "Field Employee"

# 3. PUT the whole record back, ObjectID and RowVersion included
Invoke-RestMethod -Method Put -Uri "$baseUrl/Employee" -Headers $headers -Body ($record | ConvertTo-Json -Depth 5) -ContentType "application/json"

If a PUT returns 409 Conflict, the update clashes with the record’s current state, for example because someone changed it after you read it. GET it again and reapply your change.

Delete a record (DELETE)

Send the record’s ObjectID as a query parameter or as a header named ObjectID. A success returns 204 No Content.

HTTP request
DELETE /OpsAPI_<environment>/Employee?ObjectID=<ObjectID> HTTP/1.1
Host: <cluster>.b2w.trimble.com
Authorization: Bearer <AccessToken>

Rules to remember

  • You cannot change an ObjectID through the API. It is the record’s permanent key.
  • Each action needs the matching API permission in the caller’s security role: Create, View, Edit, or Delete (question 21).
  • A read-only license cannot make changes, even if the security role would allow them.
Build your POST from a GET

If you want to put data into Ops, run a GET in that area first. It shows you the full outline of a record, and you can build your POST around it. GET /{Area}/schema returns the formal JSON schema too (it needs a token).

16

Which endpoints are available?#

Short answer

The version 26.1.2.1 catalog lists 63 functional areas and 272 operations. Most areas support GET, POST, PUT, and DELETE plus a /schema call. Search the list below, then open Swagger for the fields.

Each card’s Build button opens that endpoint in the , which writes a ready-to-run request for Postman, PowerShell, cURL, or raw HTTP.

The list reflects the version 26.1.2.1 catalog, checked October 2, 2026. Environments on other versions may differ, and their own Swagger page is always the source of truth.

Part 4

Troubleshoot

A repeatable way to find what’s wrong, an error decoder, an interactive troubleshooter, and fixes for the errors you will see most.

17

How do I troubleshoot an Ops API problem?#

Short answer

Ask the five core diagnostic questions in order. They separate the API surface, the connection, the login, and the data call, so you find the failing step quickly.

  1. API surface

    Is it the Ops API (JSON) or the older Web Services (SOAP XML)?

  2. Base URL and connectivity

    Is the base URL right, and does GET /Ping/hello succeed? Always check connectivity first.

  3. Authentication method

    Which sign-in method does the call use: user (username and password), TID, or client ID and secret?

  4. Login response, on its own

    Does the login return a token? Look at the login’s status code and body separately from the data call’s.

  5. Header authorization

    Does the data call carry the correct AccessToken in an Authorization: Bearer header?

Gather these details

  • Company and environment name
  • The Ops API URL being called
  • Endpoint and method, such as GET /Job
  • The login method
  • Status code and response body, with secrets removed
  • Date, time, and time zone of the failure
  • The tool or integration making the call
  • Whether it ever worked, and what changed
Share evidence, not secrets

Screenshots or logs of the request and response help, with credentials and tokens hidden. Never send a client ID, secret, password, or token by email, chat, or support case.

Still stuck? Contact B2W Support

Send the details above to support_b2w@trimble.com or call +1 (888) 390-8822. The error decoder’s Copy a summary button writes most of it for you.

18

What does this error mean?#

Short answer

Paste the error into the decoder: a status line, a response body, a Postman or PowerShell error, or the request URL. It works out which API and call the error came from, names the likely cause, and links to the fix.

Paste the request URL too

The URL tells the decoder the API, the environment, and the endpoint. It then checks the endpoint name against the catalog, and Check it runs the environment checker on that environment.

The decoder reads the messages the Ops API sends, such as the InternalMessage on a 403 that names the missing privilege, plus errors from Postman, PowerShell, IIS, and the network. Decoding runs entirely in your browser. Still, take tokens and secrets out of anything you copy into an email or support case.

19

Where is my call failing?#

Short answer

Answer a few questions about what you see. The troubleshooter walks the five diagnostic questions and lands on the likely cause and fix.

Tool

Troubleshooter

Prefer to read it all at once? Every cause and fix the troubleshooter can reach is also listed in question 21.

20

What do the status codes mean?#

Short answer

2xx means it worked. 4xx means the request was wrong: bad input, a bad or missing token, missing permissions, or something not found. 5xx means Ops hit an unexpected error. The same code can mean different things on the login call and on a data call.

CodeMeaningOn /LoginOn a data call
200 OKSuccessToken issuedData returned or record updated
201 CreatedRecord created–A POST succeeded
204 No ContentDone, nothing to return–A DELETE succeeded
400 Bad RequestIncomplete or malformed requestNo credentials in the headers, or the user name is invalidMissing parameters or a malformed query
401 UnauthorizedUnsigned caller or bad tokenCredentials rejectedBearer token missing, invalid, or expired
403 ForbiddenNot enough privileges–The security role lacks that API permission
404 Not FoundResource or user missingNo matching Ops user, or the System Administrator record is missingRecord not found. An HTML 404 page means a wrong URL.
406 Not AcceptableUnexpected formatThe System Administrator’s Windows account name isn’t in the expected format–
409 ConflictConflicting update–A PUT clashes with the record’s current state
422 UnprocessableBody isn’t a valid record–A POST or PUT body is missing required fields or is malformed
500 Server ErrorUnexpected internal Ops errorCapture the request, response, and time, then contact B2W Support
21

How do I fix the most common errors?#

Short answer

Find the symptom below. Each card gives the likely cause and the fix. Isolate the failing step first: connection, login, or data call.

403 Forbidden: “insufficient privileges”

A 403 almost always means the user’s Ops security role doesn’t grant the API permission the call needs. The response names the missing privilege:

Figure 9. ① The 403 status. ② The messages explain why: the call needed ApiEmployee.Read, and the user’s role doesn’t grant it.
  1. Open the user’s security role in OpsFrom their User View (Figure 3), click the role name.
  2. Find the API section and the area’s rowCheck the column for the action: View for GET, Create for POST, Edit for PUT, Delete for DELETE. A filled green dot means granted.
Figure 10. ① The API section of a security role. ② With this role, GET /Employee works (View granted), but POST /Employee returns 403 (Create not granted).
Licenses matter too

A read-only license cannot make changes in Ops, even if the security role allows them. It cannot even run a GET on employees.

Every other common error

No response

Ping fails or the connection is refused

Likely cause

The API site, the IIS web server, or the network is down entirely.

Fix

Check network connectivity, routing, and the IIS host status. If the site itself is down, contact B2W Support.

404 page

Ping returns an HTML “404” page

Likely cause

The address is wrong: a typo in the environment name, or a missing OpsAPI_ prefix.

Fix

Rebuild the URL with the formula in question 3 and try /Ping/hello again.

400

Login: “Authentication information must be specified in the request header”

Likely cause

No complete credential pair in the headers. The values may be in the URL or body, or a header name is misspelled.

Fix

Send exactly one pair as headers: tiduuid + apiSecret, clientId + clientSecret, or userName + password.

401

Login rejected

Likely cause

With a user name: Windows rejected the password. With a client ID: the ID or secret doesn’t match Ops system settings. With a TID UUID: the TID ID or User API Secret is wrong.

Fix

Re-copy the values from their source (question 8 or question 9). Ask whether anyone generated a new secret or key recently.

404

Login: user not found

Likely cause

With a user name: the account isn’t set up as an Ops user. With client credentials: the built-in System Administrator record is missing in Ops.

Fix

Confirm the user exists and is active in Ops. If the System Administrator record is missing, contact B2W Support.

404

LoginWithTID: user linkage failure

Likely cause

Trimble accepted and authenticated the person, but no Ops user matches their Trimble ID or mobile email address.

Fix

Fix the link on the Ops user record (TID / Mobile E-mail Address). Do not reset the password; the Trimble sign-in is valid.

401

Login works, then the data call returns 401

Likely cause

The bearer token is missing from the Authorization header, or it has expired.

Fix

Check the header reads Authorization: Bearer <AccessToken>. Log in again for a fresh token; they last 1 day.

200

A GET returns exactly 100 rows

Likely cause

The default page size, not missing data.

Fix

Page with $top and $skip until a page has fewer than 100 records (question 14).

XML

The request or response is XML

Likely cause

XML message bodies and .asmx URLs belong to the older SOAP Web Services. They don’t map to Ops API 2.0 endpoints.

Fix

Use the Web Services documentation and support path for it. Where it makes sense, move the integration to the Ops API.

422

POST or PUT is rejected

Likely cause

The body isn’t a valid record: a required field is missing, a field name is wrong, or the JSON is malformed.

Fix

Compare the body with a GET of an existing record or with /schema, and check the required fields in Swagger.

Part 5

Reference

Security rules, answers to common questions, a one-page cheat sheet, and definitions.

A

Security do’s and don’ts#

Do

  • Prefer TID UUID + User API Secret for people, so changes are audited to them.
  • Use client ID + secret only for unattended integrations, and limit who knows them.
  • Practice write calls in a test environment.
  • Hide tokens and secrets before sharing screenshots or logs.
  • Clear secrets from Postman variables before sharing or exporting a collection.
  • Coordinate before generating a new secret or API key that may be in use.

Don’t

  • Never send a client ID and secret over email.
  • Never put credentials in the URL or JSON body of a login call.
  • Don’t paste bearer tokens into emails, chats, or support cases. They work for a full day.
  • Don’t reset a password to fix a LoginWithTID 404. Fix the user link.
  • Don’t test changes in someone else’s environment without their request.
  • Don’t build new integrations on username and password. It is being retired.
B

Frequently asked questions#

Answers to the questions people ask most.

What is the biggest difference between a client ID + secret and TID?

A client ID and secret give system-administrator-level access. TID keeps an audit trail of what was changed and takes on the persona of the user, following the limits set in their security role.

If someone has a read-only license but their security role lets them add records through the API, can they make changes?

No. A read-only license does not have permission to make changes in Ops. It cannot even run a GET on employees.

Will API security roles follow the organization, business unit, and user structure, so people only see their own data?

Likely not. That would be a very large undertaking for the development team. Today, API permissions are set per area and per action (Create, View, Edit, Delete).

Can I change a record’s ObjectID through the API?

No. The ObjectID is the record’s permanent key. You use it to target a PUT or DELETE, but you cannot change it.

What can you do with the API?

Whatever you can do with the application, for the areas the API covers and within the caller’s permissions. See the endpoint explorer.

Is an AccessToken the same thing as a bearer token?

Yes. The login response calls it AccessToken; you send it in a header as Authorization: Bearer <AccessToken>.

How long does a token last?

One day by default, set by the Security:JWT:Lifetime site setting. Generating a new token also retires the old one, so use your latest.

Is username and password login going away?

Yes. It is going to sunset soon. Move people to TID UUID + User API Secret, and unattended integrations to client ID + secret.

Do I need to log in to use Ping or Version?

No. /Ping/hello and /Version are the two calls that need no authentication, which makes them the first check for any problem. In version 26.1.2.1, /SystemInfo also answered without a login.

Is the API URL case-sensitive?

No. /OpsAPI_<environment>, /OPSAPI_<environment>, and /opsapi_<environment> all reach the same API.

Where do I find the fields a POST needs?

Three places: the area’s section in Swagger, GET /{Area}/schema, or a GET of an existing record in that area. The last one is often the quickest.

Why does Postman show an “Auth” folder if Auth isn’t an endpoint?

It is only a folder that groups the four login requests. They all call /Login or /LoginWithTID.

Where can I read more?

Your environment’s own Swagger page, linked under Links and resources. It always matches your version.

C

Quick reference#

Everything on one screen. It prints on a single page if you print this section alone.

Addresses

API
https://{cluster}/OpsAPI_{environment}
Docs
{api}/doc/index.html
Spec
{api}/doc/v2/OpsAPI.json
Example
https://<cluster>.b2w.trimble.com/OpsAPI_<environment>

No login needed

GET
/Ping/hello → server name + your text
GET
/Version → API version
GET
/SystemInfo → TID mode

Log in · GET /Login · headers only

TID
tiduuid + apiSecret → acts as the user
Client
clientId + clientSecret → System Administrator
User
userName + password → being retired
Trimble
GET /LoginWithTID with a Trimble ID token

Data calls

Header
Authorization: Bearer <AccessToken>
Body
Content-Type: application/json
Token
Lasts 1 day; a new login retires the old one
Query
$filter $select $orderby $top $skip · 100 per page

Where credentials live

TID ID + secret
⚙ Users → User View → User API Secret
Client ID + secret
⚙ Integrations & Add-ins → Manage API Key
API URL
Ops site address, with OpsAPI_ before the site name

Five questions for every problem

  1. Ops API (JSON) or Web Services (SOAP XML)?
  2. Right URL? Does /Ping/hello answer?
  3. Which login method?
  4. Login status and body, on their own?
  5. Bearer token in the data call’s header?

Status codes

400
Bad input, or no credentials in the login headers
401
Credentials rejected, or token missing/expired
403
Security role lacks the API permission
404
Not found; on LoginWithTID, fix the user link

Never

  • Email a client ID and secret
  • Put credentials in a URL or body
  • Paste tokens into emails or cases
  • Reset a password for a LoginWithTID 404
D

Glossary#

AccessToken / bearer token
The signed token the login returns. Sent on every data call as Authorization: Bearer …. Lasts 1 day by default.
API
Application programming interface: a published way for programs to request actions from another system.
apiSecret / User API Secret
A per-user secret generated in Ops. Paired with the TID ID to log in as that user.
Base URL
The root address of an environment’s API, such as https://<cluster>.b2w.trimble.com/OpsAPI_<environment>.
Client ID / client secret
Environment-level credentials from Manage API Key. They log in as the built-in System Administrator.
Cluster
The server group that hosts an environment, such as <cluster>.b2w.trimble.com.
CRUD
Create, Read, Update, Delete: the four basic data actions, matching POST, GET, PUT, and DELETE.
Endpoint
One address and method the API answers, such as GET /Employee.
Environment
A site name: the last part of the Ops address.
Functional area
A group of related endpoints in the catalog, such as Employee or Job.
Header
A key-value pair sent with a request, such as Content-Type: application/json.
JSON
The plain-text data format the Ops API sends and receives.
JWT
JSON Web Token: the signed format of the AccessToken.
LoginWithTID
The endpoint that exchanges a Trimble ID token for an Ops access token.
ObjectID
A record’s permanent unique key (a GUID). Used to target updates and deletes. It can’t be changed.
OData
The query standard behind $filter, $select, $orderby, $top, and $skip.
Page size
The most records one GET returns: 100 by default.
Postman collection
A shared, ready-made set of requests and variables, imported into Postman.
REST
The API style the Ops API uses: one URL per resource, standard HTTP methods, JSON data.
RowVersion
A number on each record that changes when it is saved. Send it back unchanged on a PUT.
Security role
The Ops role whose API section grants Create, View, Edit, and Delete per area.
SOAP / Web Services
The older B2W API: .asmx URLs, POST-only, XML envelopes.
Status code
The three-digit result of a call, such as 200, 401, or 403.
Swagger
The interactive catalog at /doc/index.html that lists every endpoint and field.
TID (Trimble ID)
Trimble’s identity service. In TID mode, users sign in to Ops with their Trimble ID.
tiduuid / TID ID
The unique ID of a user’s Trimble identity, shown in the User API Secret dialog.
E

B2W API Help · Estimate API

B2W Estimate API Help Guide

How to reach your Estimate API, sign in, send the right headers, read and update estimate data, and solve problems when a call fails. Paste your Ops URL into the card to fill in every example.

Part 1

Understand the basics

What the Estimate API covers, how it differs from the Ops API, and where to find it.

1

What is the B2W Estimate API?#

Short answer

The Estimate API lets other software read and write B2W Estimate data: estimates and their items and components, plus the resources, organizations, and categories behind them. It is a REST API that speaks JSON, like the Ops API, but it signs in differently and needs a few extra headers.

The Estimate API v1 catalog lists 56 functional areas and 227 operations. It supports GET, POST, and PUT. There is no DELETE.

How it differs from the Ops API

Ops APIEstimate API
Address prefixOpsAPI_EstAPI_
LoginTID UUID + secret, client ID + secret, or user name + passwordActive Directory user name + password only
Extra headersNone beyond the tokenDatabaseName on every data call; ClientID and ClientSecret when Client ID Security is on
ResultsA JSON arrayAn object with an Items array
UpdatesPUT the whole recordPUT the whole record, including its AntiTamperToken
DeleteSupportedNot supported
Not supported by the Estimate API
  • DELETE.
  • Creating, updating, or modifying the cost structure in an estimate.
  • Creating, updating, or modifying container components in an estimate or in resources.
  • Creating or updating organizations in an estimate.
2

How do I find my Estimate API URL?#

Short answer

Use the same formula as the Ops API with the EstAPI_ prefix: https://{cluster}/EstAPI_{environment}. For <environment>, that is https://<cluster>.b2w.trimble.com/EstAPI_<environment>.

The path is not case-sensitive, so estapi_<environment> works too.

Check an environment

3

Where is the Estimate API documentation?#

Short answer

Add /doc/index.html to the Estimate API URL. It is a standard Swagger page with the setup notes at the top and every functional area below.

https://<cluster>.b2w.trimble.com/EstAPI_<environment>/doc/index.htmlOpen
Figure 1. Click a heading to expand it. ① Usage Guidelines covers login, Client ID Security, and the AntiTamperToken. ② Testing Guidelines links the official Postman collection and the basic tests. ③ Functional areas expand into their operations.

The machine-readable catalog is at /doc/v1/EstAPI.json. The setup sections (Post-Installation Step and Configuration) describe on-premises installs, so for cloud environments the ones to read are Usage, Testing, and Troubleshooting.

Part 2

Sign in

Get a token, then send it with the headers every Estimate call needs.

4

How do I log in and get a Bearer Token?#

Short answer

Send GET {baseUrl}/Login with userName and password headers for an Active Directory account that has access to Estimate. The AccessToken in the response is your bearer token.

  1. Use a Windows accountThe userName is the Windows account name of an Active Directory user who can access the Estimate data, written as DOMAIN\user.
  2. Send both headersCredentials go in headers only. Both userName and password are required.
  3. Copy the AccessTokenSend it as Authorization: Bearer <AccessToken> on every other call. The response also has a RefreshToken, which the docs say to ignore; it is there for future use.
Postman
GET{{BaseURL}}/Login

Headers

userName

{{UserName}} (DOMAIN\user)

password

{{Password}}

Body

none

Login never takes a body.

Login returnsMeaning
200 OKA JWT with the AccessToken (and a RefreshToken to ignore).
400A header is missing or invalid. With no headers, the API answers {"Error":"Both userName and password must be specified in the request header"}.
401The user is not authorized.
500The server hit an internal error. Capture the details and contact B2W Support.

Is a token expired, or whose is it? Paste it into the . It shows when the token was issued and expires, and who it belongs to. It decodes the token on this page only and clears it when you close the window.

This login uses a real Windows password

Never send a password by email, and never paste one into a support case or chat. To test, use an account you are allowed to use.

5

Which headers does every call need?#

Short answer

Every data call needs Authorization: Bearer <AccessToken> and a DatabaseName header naming your Estimate database. Add ClientID and ClientSecret when Client ID Security is on, and EstimateREF on the lookups that belong to one estimate.

HeaderWhenValue
AuthorizationEvery data callBearer <AccessToken> from Login
DatabaseNameEvery data callYour Estimate database. The official collection’s placeholder is B2WSample.
ClientID · ClientSecretWhen Client ID Security is onThe values set in the API
EstimateREF15 estimate-specific lookups (below)The ObjectID of the estimate
Content-TypePOST and PUTapplication/json

Client ID Security

Client ID Security is optional and set when the API is installed. When it is on, every call must include ClientID and ClientSecret headers that match the API’s values. If they don’t match, the call returns 401, the same code as a bad token.

Calls that need EstimateREF

These lookups return the values that can be used on one estimate, so they need the estimate’s ObjectID in an EstimateREF header:

  • /Estimate/BidAs
  • /Estimate/EquipmentRateClass
  • /Estimate/EstimateType
  • /Estimate/EstimateStatus
  • /Estimate/JobCostID
  • /Estimate/LaborRateClass
  • /Estimate/MinorityType
  • /Estimate/UserDefinedField
  • /Estimate/WorkRule
  • …/Organization/{Type}/Category for Competitor, Customer, EngineerArchitect, Manufacturer, Subcontractor, and Vendor
“The user is not authorized for this API.”

That is the 401 message the API returns when a data call has no valid credentials. Check the bearer token first, then the ClientID and ClientSecret if Client ID Security is on.

6

How do I set up the Estimate Postman collection?#

Short answer

Download the official EstAPI collection from the docs, import it into Postman, and fill in six collection variables. Its pre-request script logs in for you before every request, so you never copy a token by hand.

  1. Download the collectionClick Download the Estimate collection. It is the official collection from the API docs, also linked under Testing Guidelines. It has 281 requests.
  2. Import itIn Postman, press Ctrl+O and drop the file in. The EstAPI collection appears.
  3. Fill in the variablesClick the collection, open Variables, set the values below, and save.
  4. Send any requestStart with Ping, then any GET. The collection handles login and the extra headers.
VariableWhat goes in itExample
BaseURLThe Estimate API URL (the file ships with http://localhost/EstAPI)https://<cluster>.b2w.trimble.com/EstAPI_<environment>
DatabaseNameYour Estimate databaseB2WSample (placeholder)
UserNameActive Directory account, as domain\usernameDOMAIN\jsmith
PasswordThat account’s passwordYour own value
ClientID · ClientSecretOnly when Client ID Security is onLeave blank otherwise
TokenSet automatically by the pre-request scriptLeave it
What the pre-request script does

Before each request it calls {{BaseURL}}/login with your user name and password, saves the AccessToken as the collection’s bearer token, and adds your ClientID and ClientSecret headers. Every request already sends DatabaseName.

Part 3

Make calls

Read and filter estimate data, update records safely, and find the right endpoint.

7

How do I read, filter, and page Estimate data?#

Short answer

GET returns an object whose Items array holds the records, up to 100 per call. Filter, sort, and page with the same OData options as the Ops API: $filter, $select, $orderby, $top, and $skip.

Postman
GET{{BaseURL}}/Estimate?$top=5

Headers

DatabaseName

{{DatabaseName}}

ClientID · ClientSecret

Added by the pre-request script

Authorization

Bearer Token

{{Token}}, set by the pre-request script

The in the request builder lists each endpoint’s fields and writes the $filter for you, with text quoted, IDs left unquoted, and dates in the format the API expects.

Response · 200 OK (shortened catalog example)
{
  "Items": [
    {
      "AntiTamperToken": "string",
      "ObjectID": "32b66b04-0fdc-409f-8e10-aa6f5cf0fc6e",
      "Number": "0006",
      "Name": "Elm Street Bridge Improvements, Manchester",
      "EstimateStatus": "Signed",
      "EstimateType": "Public",
      "BidAs": "General Contractor",
      "BidDate": "2018-12-28T13:00:00",
      "PrimaryCustomerName": "City Of Manchester",
      "EstimatorName": "Paul Smith"
    }
  ]
}

Filter examples

Postman URLs
# One estimate by number
{{BaseURL}}/Estimate?$filter=Number eq '0006'

# A few fields, sorted
{{BaseURL}}/Estimate?$select=ObjectID,Number,Name&$orderby=Number

# From the official collection: GUIDs go without quotes
{{BaseURL}}/Estimate/MinorityParticipationRequirement?$filter=EstimateREF eq 02E2BD02-B667-4478-A1C6-76DEDFB8958F
Exactly 100 records? Ask for the next page.

The page size is 100 by default. Add $top=100&$skip=100, then $skip=200, until a page has fewer than 100 records.

8

How do I create or update Estimate records?#

Short answer

POST creates and PUT updates. To update, GET the record, change only the fields you need, and PUT the entire record back with its AntiTamperToken unchanged.

Why the AntiTamperToken matters

Every GET returns an AntiTamperToken. A PUT must send it back with the same value. It protects properties that are returned for information only, such as ObjectID, from being changed. The docs also warn that a PUT with missing fields can delete values from the fields you left out, which is why you always send the whole record.

PowerShell · get, change, put
# 1. GET the record you want to change
$result   = Invoke-RestMethod -Uri "$baseUrl/Estimate" -Headers $headers -Body @{ '$filter' = "Number eq '0006'" }
$estimate = $result.Items | Select-Object -First 1

# 2. Change only what you need. Leave AntiTamperToken and ObjectID as they are.
$estimate.BidLocation = "Manchester, NH"

# 3. PUT the whole record back
Invoke-RestMethod -Method Put -Uri "$baseUrl/Estimate" -Headers $headers -Body ($estimate | ConvertTo-Json -Depth 10) -ContentType "application/json"
PUT returnsMeaning
200 OKThe record was updated.
400The body doesn’t contain the record.
403The operation is not allowed, for example one of the unsupported changes in question 1.
404The record wasn’t found.
422The body isn’t a valid record. Compare it with a fresh GET or with /schema.
Try changes in a test environment first

POST and PUT change real estimates. Try them in a test environment first, and never run them against someone else’s environment unless they asked for the change.

9

Which endpoints are available?#

Short answer

The Estimate API v1 catalog lists 227 operations. Most areas support GET, POST, and PUT plus a /schema call; some are read-only. Search below, then check Swagger for the fields.

Each card’s Build button opens that endpoint in the , which adds the DatabaseName and EstimateREF headers for you and writes the request for Postman, PowerShell, cURL, or raw HTTP.

Part 4

Troubleshoot

The basic tests from the Estimate API docs, and fixes for the errors you will see most.

10

What does this error mean?#

Short answer

Paste the error into the decoder: a status line, a response body, a Postman or PowerShell error, or the request URL. It names the likely cause and links to the fix.

It knows the Estimate API’s own messages, such as “The user is not authorized for this API.” and “Operation is not allowed”. It also reads SQL Server errors like “Login failed for user ‘NT AUTHORITY\NETWORK SERVICE’”, and checks pasted request headers for a missing DatabaseName, EstimateREF, or Bearer. Decoding runs entirely in your browser.

11

How do I troubleshoot the Estimate API?#

Short answer

Run the two basic tests in order: an app-up test with /Ping/hello, then a login test. Don’t go further until both pass. Then check the data call’s headers.

  1. App-up test

    GET /Ping/hello should return 200 and (server) hello|. If it doesn’t, check that IIS is running, that the EstAPI application pool is running, and that the URL is correct. The environment checker in question 2 runs this test for you.

  2. Login test

    GET /Login with userName and password headers should return 200 and an AccessToken. Any other code points at the account (question 4).

  3. Data call headers

    Check Authorization: Bearer, DatabaseName, the ClientID and ClientSecret if Client ID Security is on, and EstimateREF for estimate-specific lookups.

Common errors

400

Login: “Both userName and password must be specified in the request header”

Likely cause

One or both headers are missing, or they were sent in the URL or body.

Fix

Send both userName (DOMAIN\user) and password as headers.

401

Login: user is not authorized

Likely cause

The domain controller rejected the account, or the account has no access to the Estimate data.

Fix

Confirm the account name format and password, and that the user can access Estimate.

401

Data call: “The user is not authorized for this API.”

Likely cause

The bearer token is missing, invalid, or expired, or the ClientID or ClientSecret is wrong when Client ID Security is on.

Fix

Log in again for a fresh token and check the Authorization header. Then check the ClientID and ClientSecret headers.

Wrong data

Empty results, or data from the wrong company

Likely cause

The DatabaseName header is missing or names the wrong database.

Fix

Confirm the Estimate database name and resend.

SQL

“Login failed for user ‘NT AUTHORITY\NETWORK SERVICE’”

Likely cause

The API runs as the Network Service account, which needs db_owner access to the Estimate database (the docs’ Post-Installation Step).

Fix

On-premises: grant that access using the ConfigureDB commands. Cloud: contact B2W Support.

403

PUT: “Operation is not allowed”

Likely cause

The change is one the API doesn’t support, such as cost structure, container components, or organizations in an estimate.

Fix

Make that change in Estimate itself. There is no API route for it.

422

POST or PUT is rejected

Likely cause

The body isn’t a valid record, or a PUT left out fields or changed the AntiTamperToken.

Fix

GET the record again and PUT the whole record back with its AntiTamperToken unchanged.

Still stuck? Contact B2W Support

Email support_b2w@trimble.com or call +1 (888) 390-8822. Include the environment name, the endpoint and method, the status code and response with secrets removed, and the date, time, and time zone. The error decoder’s Copy a summary button writes most of it for you.

B2W API Help · Management Reporting API

B2W Management Reporting API Help Guide

How to reach your Management Reporting (MR) API, sign in, send the right headers, and pull report data from the Data Warehouse. Paste your Ops URL into the card to fill in every example.

Download Postman Download the MR collection Open the API docs
Part 1

Understand the basics

What the MR API covers, where its data comes from, and where to find it.

1

What is the Management Reporting API?#

Short answer

The MR API is a read-only REST API over the B2W Management Reporting Data Warehouse. It returns report data such as estimates, pay items, tasks, cost components, bid results, change orders, and vendor and subcontractor quotes. Every operation is a GET.

The MR API v2 catalog lists 42 functional areas and 106 operations: a data call and a /schema call for each area, plus Login and Ping.

Report data, not live estimates

Records come from the Data Warehouse, not straight from Estimate. Each record shows where it came from (SourceDatabaseName) and when (LastRetrievedFromSourceDatabaseOn). If the API shows old numbers, check those fields first. To change data, use Estimate or the Estimate API.

2

How do I find my MR API URL?#

Short answer

Use the same formula with the MRAPI_ prefix: https://{cluster}/MRAPI_{environment}. For <environment>, that is https://<cluster>.b2w.trimble.com/MRAPI_<environment>.

Check an environment

3

Where is the MR API documentation?#

Short answer

Add /doc/index.html to the MR API URL. Like the Estimate API, it is a standard Swagger page with setup notes at the top and every functional area below.

https://<cluster>.b2w.trimble.com/MRAPI_<environment>/doc/index.htmlOpen
Figure 1. ① Usage Guidelines covers login and Client ID Security. ② Testing Guidelines links the official Postman collection. ③ Functional areas, each read from the Data Warehouse.

The machine-readable catalog is at /doc/v2/MRAPI.json.

Part 2

Sign in

Get a token, then send it with the headers every MR call needs.

4

How do I log in and get a Bearer Token?#

Short answer

Exactly like the Estimate API: send GET {baseUrl}/Login with userName (DOMAIN\user) and password headers for an Active Directory account with access to Management Reporting. The AccessToken in the response is your bearer token.

Postman
GET{{BaseURL}}/Login

Headers

userName

{{UserName}} (DOMAIN\user)

password

{{Password}}

The responses match the Estimate API: 200 with the AccessToken, 400 when a header is missing (the API answers "Both userName and password must be specified in the request header"), 401 when the user is not authorized, and 500 for server errors.

Is a token expired, or whose is it? Paste it into the . It shows when the token was issued and expires, and who it belongs to. It decodes the token on this page only and clears it when you close the window.

5

Which headers does every call need?#

Short answer

Every data call needs Authorization: Bearer <AccessToken> and a DatabaseName header naming the Data Warehouse database. Add ClientID and ClientSecret when Client ID Security is on, and EstimateREF on the eight calls that return one estimate’s items.

HeaderWhenValue
AuthorizationEvery data callBearer <AccessToken> from Login
DatabaseNameEvery data callThe Management Reporting Data Warehouse database. The official collection’s placeholder is B2WDataWarehouse.
ClientID · ClientSecretWhen Client ID Security is onThe values set in the API; a mismatch returns 401
EstimateREFThe eight estimate-specific calls belowThe ObjectID of the estimate

Calls that need EstimateREF

For one estimate (send EstimateREF)Across all estimates (no EstimateREF)
/Estimate/PayItem · /Estimate/PayItemDetail/Estimate/PayItemAll
/Estimate/IndirectItem · /Estimate/IndirectItemDetail/Estimate/IndirectItemAll
/Estimate/Task · /Estimate/TaskDetail/Estimate/TaskAll
/Estimate/WBSLevel · /Estimate/WBSLevelDetail/Estimate/WBSLevelAll

The Detail versions return the same items with full information. Get an estimate’s ObjectID from GET /Estimate first.

6

How do I set up the MR Postman collection?#

Short answer

Download the official MRAPI collection from the docs, import it, and fill in its variables. Like the Estimate collection, its pre-request script logs in for you before every request.

  1. Download the collectionClick Download the MR collection. It is the official collection from the API docs, also linked under Testing Guidelines. It has 107 requests.
  2. Import itPress Ctrl+O in Postman and drop the file in.
  3. Fill in the variablesSet the values below on the collection’s Variables tab and save.
VariableWhat goes in itExample
BaseURLThe MR API URL (the file ships with http://localhost/MRAPI)https://<cluster>.b2w.trimble.com/MRAPI_<environment>
DatabaseNameThe Data Warehouse databaseB2WDataWarehouse (placeholder)
UserName · PasswordActive Directory account, as domain\usernameYour own values
ClientID · ClientSecretOnly when Client ID Security is onLeave blank otherwise
EstimateREFAn estimate’s ObjectID, for the estimate-specific requestsDA45D31C-05FC-4C64-B1C8-8CE3E8E69D23 (sample)
TokenSet automatically by the pre-request scriptLeave it
Part 3

Make calls

Pull report data, page through it, and find the right endpoint.

7

How do I read, filter, and page report data?#

Short answer

Every GET returns an Items array and a Pagination block that tells you how many records exist. Use OData to filter and page; contains() works for text searches.

Postman
GET{{BaseURL}}/Estimate/PayItem?$filter=contains(Description, 'Mobilization')

Headers

DatabaseName

{{DatabaseName}}

EstimateREF

{{EstimateREF}}

Authorization

Bearer Token

{{Token}}, set by the pre-request script

The in the request builder lists each endpoint’s fields and writes the $filter for you, with text quoted, IDs left unquoted, and dates in the format the API expects.

Response · GET /Estimate (shortened catalog example)
{
  "Items": [
    {
      "Title": "Fox Hill Development",
      "ObjectID": "02e2bd02-b667-4478-a1c6-76dedfb8958f",
      "EstimateNumber": "0012",
      "BidNumber": "64687",
      "EstimateStatus": "Pending",
      "SourceDatabaseName": "B2WSample",
      "LastRetrievedFromSourceDatabaseOn": "2025-12-07T23:40:17.823",
      "TotalBidPriceWithTax": 12627661.59
    }
  ],
  "Pagination": {
    "CurrentPage": "…/Estimate?$orderBy=Title&$skip=0&$top=5",
    "ItemsOnPage": 1,
    "PageSize": 5,
    "TotalItems": 1
  }
}
Use TotalItems to page

Pagination.TotalItems tells you how many records match. Keep adding $skip in steps of your $top (100 at most) until you have them all.

8

Which endpoints are available?#

Short answer

The MR API v2 catalog lists 106 operations, all GET. Each area has a data call and a /schema call. Search below, then check Swagger for the fields.

Each card’s Build button opens that endpoint in the , which adds the DatabaseName and EstimateREF headers for you and writes the request for Postman, PowerShell, cURL, or raw HTTP.

Part 4

Troubleshoot

The basic tests from the MR API docs, and fixes for the errors you will see most.

9

What does this error mean?#

Short answer

Paste the error into the decoder: a status line, a response body, a Postman or PowerShell error, or the request URL. It names the likely cause and links to the fix.

It knows the MR API’s messages and SQL Server errors such as “Login failed for user ‘NT AUTHORITY\NETWORK SERVICE’”. Paste a successful response and it reads the Pagination block and LastRetrievedFromSourceDatabaseOn too, which answers “why is data missing?” and “why are the numbers old?”. Decoding runs entirely in your browser.

10

How do I troubleshoot the MR API?#

Short answer

Run the app-up test with /Ping/hello, then the login test. Don’t go further until both pass. Then check the headers, especially DatabaseName and EstimateREF.

  1. App-up test

    GET /Ping/hello should return 200 and (server) hello|. If not, check that IIS and the MRAPI application pool are running and that the URL is correct. The environment checker in question 2 runs this for you.

  2. Login test

    GET /Login with userName and password headers should return an AccessToken.

  3. Data call headers

    Check Authorization: Bearer, DatabaseName, the client values if Client ID Security is on, and EstimateREF on estimate-specific calls.

Common errors

401

Data call: “The user is not authorized for this API.”

Likely cause

The bearer token is missing, invalid, or expired, or the ClientID or ClientSecret is wrong when Client ID Security is on.

Fix

Log in again for a fresh token, then check the client headers.

Wrong data

Empty results or the wrong company’s data

Likely cause

The DatabaseName header is missing or names the wrong Data Warehouse database.

Fix

Confirm the Data Warehouse database name and resend.

No items

Pay items, tasks, or WBS levels come back empty

Likely cause

The EstimateREF header is missing or isn’t an estimate in this Data Warehouse.

Fix

Get the estimate’s ObjectID from GET /Estimate, or use the …All version of the call.

Old data

“The API shows old numbers”

Likely cause

The Data Warehouse hasn’t been reloaded from the source Estimate database since the change.

Fix

Check LastRetrievedFromSourceDatabaseOn on the record, and the Data Warehouse load for that source database.

SQL

“Login failed for user ‘NT AUTHORITY\NETWORK SERVICE’”

Likely cause

The API’s Network Service account lacks db_owner access to the Data Warehouse database, or the API’s SQL Server connection string is wrong.

Fix

On-premises: grant the access and verify the connection string (the docs’ Post-Installation Step). Cloud: contact B2W Support.

Still stuck? Contact B2W Support

Email support_b2w@trimble.com or call +1 (888) 390-8822. Include the environment name, the endpoint and method, the status code and response with secrets removed, and the date, time, and time zone. The error decoder’s Copy a summary button writes most of it for you.