Skip to content

Address book

Your address book holds the subcontractors and suppliers you work with: each company, its office, the trades you’ve assigned it, the company lists it’s on, and its contacts. These endpoints read it, add to it and change its companies, for example to sync the companies and contacts in your CRM into E1.

GET /api/tender/builder/v1/companies/{companyId}/address-book/companies
POST /api/tender/builder/v1/companies/{companyId}/address-book/companies
GET /api/tender/builder/v1/companies/{companyId}/address-book/companies/{addressBookCompanyId}
PATCH /api/tender/builder/v1/companies/{companyId}/address-book/companies/{addressBookCompanyId}
POST /api/tender/builder/v1/companies/{companyId}/address-book/companies/{addressBookCompanyId}/archive
POST /api/tender/builder/v1/companies/{companyId}/address-book/companies/{addressBookCompanyId}/restore
GET /api/tender/builder/v1/companies/{companyId}/address-book/companies/{addressBookCompanyId}/contacts
POST /api/tender/builder/v1/companies/{companyId}/address-book/companies/{addressBookCompanyId}/contacts

The GET endpoints need address-book/read, and the POST and PATCH endpoints need address-book/write. The address book must be enabled for your company in E1.

You only ever see your own address book, and only what it shows in E1: archived and merged companies, company requests you haven’t approved, and contacts that are archived or still pending are left out. A company or contact you added from an E1 network profile shows the name, phone and email from that profile wherever you haven’t entered your own. Nothing else from the profile is returned.

FieldTypeNotes
idstringNumeric string. The addressBookCompanyId used in the paths above, and in an invitation’s invitee.
namestring | null
phonestring | null
addressobject | nullThe office address, in the same shape as a project’s address. null if none was entered.

GET .../address-book/companies returns your companies, oldest first.

Query parameterNotes
nameOptional. Only list companies whose name contains this text, ignoring case.
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 and the same name. The cursor is signed and tied to the listing and filter it came from: pass it back unchanged. A cursor that was modified, or that came from a different listing, returns 400.

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/address-book/companies?name=acme"
{
"data": [
{
"id": "3001",
"name": "Acme Joinery",
"phone": "03 9000 0000",
"address": {
"line1": "1 Collins Street",
"line2": null,
"line3": null,
"suburb": "Melbourne",
"city": null,
"district": null,
"province": null,
"region": null,
"state": { "name": "Victoria", "shortName": "VIC" },
"postcode": "3000",
"country": { "name": "Australia", "code": "AU" }
}
}
],
"_metadata": {
"nextCursor": null,
"hasNextPage": false
}
}

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

GET .../address-book/companies/{addressBookCompanyId} returns one company as data. As well as the fields above, it includes:

FieldTypeNotes
faxstring | null
tradesobject[]The trades you’ve assigned to the company: id and name.
listsobject[]The company lists it’s on: id and name.
custom1, custom2, custom3string | nullThe values of your address book’s three custom fields. Their labels are set in your address book settings in E1.
{
"data": {
"id": "3001",
"name": "Acme Joinery",
"phone": "03 9000 0000",
"address": null,
"fax": "03 9000 0001",
"trades": [{ "id": "501", "name": "Joinery" }],
"lists": [{ "id": "601", "name": "Preferred" }],
"custom1": "ABN 12 345 678 901",
"custom2": null,
"custom3": null
}
}

GET .../address-book/companies/{addressBookCompanyId}/contacts returns the company’s contacts, oldest first. It takes limit and cursor and pages the same way as the company list.

FieldTypeNotes
idstringNumeric string. The addressBookContactId in an invitation’s invitee.
firstNamestring
lastNamestring
emailstring | null
phonestring | null
positionTitlestring | null
isPreferredbooleanWhether this is the company’s preferred contact.
typesstring[]What the contact handles: Estimating, Construction, both or neither.
{
"data": [
{
"id": "4001",
"firstName": "Jo",
"lastName": "Smith",
"email": "jo.smith@example.com",
"phone": "0400 000 000",
"positionTitle": "Estimator",
"isPreferred": true,
"types": ["Estimating"]
}
],
"_metadata": {
"nextCursor": null,
"hasNextPage": false
}
}

POST .../address-book/companies adds a company to your address book and returns it as data, in the same shape as reading a company, with 201. Wrap the company in data:

FieldTypeNotes
namestringRequired. Up to 100 characters.
phone, faxstring | nullOptional. Up to 16 characters.
businessIdentifierstring | nullOptional. The company’s registered business identifier in your country: its ABN in Australia, NZBN in New Zealand, or company registration number in the UK and Ireland. Up to 16 characters; spaces are ignored.
addressobject | nullOptional. The office address, in your own country: line1 (required), line2, line3, suburb, state (its short name, such as VIC) and postcode (required).
custom1, custom2, custom3string | nullOptional. The values of your address book’s custom fields.
Terminal window
curl -sS -X POST \
-H "Authorization: Bearer $E1_ACCESS_TOKEN" \
-H "x-e1-client-id: $E1_CLIENT_ID" \
-H "content-type: application/json" \
-d '{"data":{"name":"Acme Joinery","businessIdentifier":"51824753556","address":{"line1":"1 Collins Street","suburb":"Melbourne","state":"VIC","postcode":"3000"}}}' \
"$E1_API_BASE/api/tender/builder/v1/companies/$E1_COMPANY_ID/address-book/companies"

If your address book already has a company with the same business identifier, nothing is added. You get 409 DUPLICATE_COMPANY, with the existing company’s ID as the error’s id, so you can link your record to it instead:

{
"_errors": [
{
"code": "DUPLICATE_COMPANY",
"detail": "Your address book already has a company with this business identifier. `id` is that company.",
"id": "3001"
}
]
}

Archived and merged companies don’t count as duplicates. A company without a business identifier is never treated as a duplicate, so look it up by name first if you might have added it before.

Adding a company never connects it to, or notifies, an E1 network profile.

POST .../address-book/companies/{addressBookCompanyId}/contacts adds a contact to one of your companies and returns it as data, in the same shape as a company’s contacts, with 201. Wrap the contact in data:

FieldTypeNotes
firstNamestringRequired. Up to 100 characters.
lastNamestring | nullOptional. Up to 100 characters.
emailstring | nullOptional.
phonestring | nullOptional. Up to 16 characters.
positionTitlestring | nullOptional. Up to 100 characters.
isPreferredbooleanOptional. Whether this is the company’s preferred contact. Defaults to false.
typesstring[]Required. At least one of Estimating and Construction.
{
"data": {
"firstName": "Jo",
"lastName": "Smith",
"email": "jo.smith@example.com",
"positionTitle": "Estimator",
"types": ["Estimating"]
}
}

If the company already has a contact with the same email, ignoring case, nothing is added. You get 409 DUPLICATE_CONTACT, with the existing contact’s ID as the error’s id. The same person can be a contact at more than one company.

If another addition to your address book is still being saved when you send yours, you get 409 CREATION_IN_PROGRESS. Send the request again shortly.

PATCH .../address-book/companies/{addressBookCompanyId} changes a company in your address book and returns it as data, in the same shape as reading a company, with 200. Wrap the changes in data and send only the fields you want to change. A field you leave out keeps its value, and you must send at least one.

FieldTypeNotes
namestringUp to 100 characters. For a company you added from an E1 network profile, this is your own name for it; the profile keeps its name. Can’t be null.
phone, faxstring | nullUp to 16 characters. null clears it.
addressobjectReplaces the whole office address, in the same shape as when adding a company. Can’t be null.
tradeIdsstring[]Replaces the company’s trades. Each must be the id of a trade in your address book, as in a company’s trades. [] removes them all.
listIdsstring[]Replaces the company lists the company is on. Each must be the id of a company list in your address book, as in a company’s lists. [] takes it off them all.
custom1, custom2, custom3string | nullUp to 255 characters. Only a custom field your address book has set up takes a value. null clears it.
Terminal window
curl -sS -X PATCH \
-H "Authorization: Bearer $E1_ACCESS_TOKEN" \
-H "x-e1-client-id: $E1_CLIENT_ID" \
-H "content-type: application/json" \
-d '{"data":{"phone":"03 9111 1111","tradeIds":["501","502"],"custom1":null}}' \
"$E1_API_BASE/api/tender/builder/v1/companies/$E1_COMPANY_ID/address-book/companies/3001"

A trade or list ID that isn’t in your address book, or a value for a custom field your address book doesn’t have, is 400 VALIDATION_FAILED and nothing is changed. Taking a trade off a company also takes its contacts off your contact lists for that trade, as it does in E1. You can’t update an archived company; restore it first.

POST .../address-book/companies/{addressBookCompanyId}/archive archives a company and its contacts, as archiving it in E1 does. It then drops out of your listings and reading it returns 404, but you can still restore it by its ID.

POST .../address-book/companies/{addressBookCompanyId}/restore brings it back with the contacts you entered yourself. For a company you added from an E1 network profile, its contacts are synced from the profile again.

Neither takes a body. Both return 204 with no content. Both are safe to retry: archiving an archived company, or restoring an active one, changes nothing and still returns 204.

Terminal window
curl -sS -X POST \
-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/address-book/companies/3001/archive"

A merged company can’t be archived or restored, and returns 404.

StatusWhen
400limit, name, the company ID or the body isn’t valid, or the cursor was modified or came from a different listing (INVALID_CURSOR). A business identifier that isn’t valid for your country (such as an ABN that fails its checksum), a state that isn’t in your country, a trade or list ID that isn’t in your address book, or a value for a custom field your address book doesn’t have, is VALIDATION_FAILED.
401The token doesn’t carry address-book/read (for a GET) or address-book/write (for a POST or PATCH).
403The address book isn’t enabled for your company.
404The address-book company doesn’t exist, belongs to another company, or is merged. An archived company is also 404, except when you archive or restore it.
409DUPLICATE_COMPANY or DUPLICATE_CONTACT: the record is already there, and the error’s id is it. CREATION_IN_PROGRESS or UPDATE_IN_PROGRESS: another change is still being saved, so try again shortly.