Skip to content

Projects

A project is a piece of work a builder is running — put to market for pricing, and tracked through to award.

GET /api/tender/builder/v1/companies/{companyId}/tender-projects
GET /api/tender/builder/v1/companies/{companyId}/tender-projects/{projectId}
PUT /api/tender/builder/v1/companies/{companyId}/tender-projects/{projectId}

Reads need projects/read; the update needs projects/write.

FieldTypeNotes
idstringNumeric string. Stable for the life of the project.
namestring
visibility"open" | "closed"closed projects are invite-only.
budget.amountnumber | null
budget.categorystring | null
quotesDueDatestring | nullYYYY-MM-DD.
startDatestring | nullYYYY-MM-DD.
endDatestring | nullYYYY-MM-DD.
category.idstring | null
category.namestring | null
internalRefstring | nullYour own reference, if one has been set.
docRequests"auto" | "manual"Whether document requests are approved automatically.
contact.namestring | null
contact.emailstring | null
contact.phonestring | null
addressobject | nullStructured address; every part is individually nullable.

GET .../tender-projects returns the company’s tender projects, oldest first, filtered to those your registration grants access to.

Query parameterNotes
limitOptional. Page size, 1 to 100. Defaults to 25.
cursorOptional. The _metadata.nextCursor from the previous page.

The list is paginated. While _metadata.hasNextPage is true, request the next page with cursor set to _metadata.nextCursor. The cursor is signed and tied to the listing it came from: pass it back unchanged. A cursor that was modified, or that came from a different listing, returns 400.

Because the list is filtered to your registration, a page can hold fewer than limit projects, or none, while hasNextPage is still true. Keep following nextCursor until hasNextPage is false.

Terminal window
curl -sS \
-H "Authorization: Bearer $E1_ACCESS_TOKEN" \
-H "x-e1-client-id: $E1_CLIENT_ID" \
"$E1_API_BASE/api/tender/builder/v1/companies/$E1_COMPANY_ID/tender-projects"
{
"data": [
{
"id": "198578",
"name": "Main Street Development",
"visibility": "open",
"budget": { "amount": 2500000, "category": "Commercial" },
"quotesDueDate": "2026-05-15",
"startDate": "2026-06-01",
"endDate": "2026-12-01",
"category": { "id": "12", "name": "Commercial" },
"internalRef": "MSD-2026",
"docRequests": "manual",
"contact": {
"name": "Dana Okafor",
"email": "dana@example.com",
"phone": "+61 3 9000 0000"
},
"address": null
}
],
"_metadata": {
"nextCursor": null,
"hasNextPage": false
}
}

There is no filter for projects changed since a given time yet. To keep a copy in sync, page through the whole list.

PUT .../tender-projects/{projectId} replaces the editable fields. It is a full replacement, not a patch: send every writable field, because an omitted required field is a validation error and an omitted nullable field is read as null.

Read-only fields are accepted in the body and ignored, so sending back an object you just read will not fail — it simply will not change them.

FieldOn update
nameWritable, required
visibilityWritable, required
quotesDueDateWritable, required
docRequestsWritable, required
contact.name, contact.emailWritable, required
startDate, endDateWritable, nullable
internalRefWritable, nullable
contact.phoneWritable, nullable
id, budget, category, addressRead-only

contact.email must be a valid email address, and the date fields must be YYYY-MM-DD.

Terminal window
curl -sS -X PUT \
-H "Authorization: Bearer $E1_ACCESS_TOKEN" \
-H "x-e1-client-id: $E1_CLIENT_ID" \
-H "content-type: application/json" \
-d '{
"data": {
"name": "Main Street Development",
"visibility": "open",
"quotesDueDate": "2026-05-15",
"startDate": "2026-06-01",
"endDate": "2026-12-01",
"internalRef": "MSD-2026",
"docRequests": "manual",
"contact": {
"name": "Dana Okafor",
"email": "dana@example.com",
"phone": "+61 3 9000 0000"
}
}
}' \
"$E1_API_BASE/api/tender/builder/v1/companies/$E1_COMPANY_ID/tender-projects/198578"

The response is the updated project in the same shape as a read.

Packages are classified by trade discipline. The list is per-company and read with trade-disciplines/read:

GET /api/tender/builder/v1/companies/{companyId}/trade-disciplines

Each entry is an id and a name. Use the id when creating or updating a package — see Packages.