All error responses share the same envelope (see Conventions ):
{ "code" : " ... " , "detail" : " ... " , "source" : { "parameter" : " ... " } }
source.parameter is present only on validation errors and points at the request field that failed.
codeMeaning What to do CLIENT_ID_HEADER_MISSINGThe x-e1-client-id header was not sent. Add the header to every request. See Authentication . INVALID_CURSORA pagination cursor was modified, or came from a different listing (another company, project or filter). Pass _metadata.nextCursor back unchanged with the same filters, or start again without a cursor. VALIDATION_FAILEDThe request was refused as invalid. Check the parameters against the endpoint’s page. UPDATE_FAILEDA document update or delete was refused, usually because of a pending addendum. detail says why. See When writes are refused . Validation error (various codes, e.g. INVALID_PARAMETER) A path parameter was malformed. source.parameter identifies the field. Fix the offending parameter; the field name is in source.parameter.
code / detailLikely cause What to do CLIENT_ID_HEADER_MISMATCHThe x-e1-client-id header value does not match the client_id inside the bearer token. Ensure the header matches the credential you used at the token endpoint. Unauthorised (plain body)The bearer token is invalid or expired. Request a new token. See Authentication . Unauthorised (plain body)The companyId in the URL is not registered against your application. Contact E1 support to add the registration. Unauthorised (plain body)The permission on your registration is not published. Contact E1 support — this is a provisioning issue on our side. Unauthorised (plain body)The token’s scopes, intersected with your permission’s scopes, don’t include the scope the route requires. Request your token with the required scope, or ask support to add it to your permission. For the Supplier API you need speci-finder/read.
code / detailLikely cause What to do 403 / Access deniedThe supplier company you are calling for does not hold the required E1 licence for this endpoint (the Supplier API requires the Supplier Professional Plus licence or an equivalent regional variant). Confirm with the customer that their E1 licence covers Speci-finder access. Contact E1 support if you believe the licence is in place but the call is still rejected.
Returned by the addenda endpoints when the project’s addenda are in a state that refuses the request.
codeMeaning What to do ADDENDUM_ALREADY_PENDINGThe project already has a pending addendum. Use the pending addendum, or have the builder issue or cancel it first. DUPLICATE_NAMEAnother addendum on the project has that name. Choose a different name. ADDENDUM_ISSUEDThe addendum has been issued and is read-only. No retry will succeed. ADDENDUM_FINALISINGThe builder has just issued the addendum and E1 is still processing it. Retry after a short delay. UNCONFIRMED_MATRIX_CHANGESThe project has draft package changes that starting an addendum would discard. Ask the builder to confirm or discard them in E1. CONFLICTThe addendum can’t be changed right now for another reason. Retry later; contact support if it persists.
codeMeaning What to do (WAF response, no JSON body guaranteed) Your (bearer token, x-e1-client-id) bucket has exceeded 100 requests in a 5-minute window. Back off and retry after the window rolls over. See Rate limits for the exact limit and Retry guidance below.
codeMeaning What to do FETCH_FAILEDThe External API could not fetch data from the underlying E1 platform. Retry with exponential backoff. If persistent, contact support. INTERNAL_SERVER_ERRORSomething unexpected broke on our side. Retry with exponential backoff. If persistent, contact support.
Retry 5xx responses with exponential backoff (e.g. 1s, 2s, 4s, 8s, up to ~60s). Do not retry aggressively.
Retry 429 responses only after backing off. The API does not emit a Retry-After header — back off exponentially or wait until the 5-minute window has rolled over. See Rate limits — If you hit a throttle .
Do not retry other 4xx responses (400, 403) — the request or the underlying licence needs to change before it will succeed.
On 401 after a previously-succeeding call pattern , discard any cached token and fetch a new one before retrying once. If the retry fails, stop and investigate.
A 200 with { "data": [] } is not an error. It means the call succeeded but nothing matched. Common causes:
The supplier account has no Speci-finder keywords configured.
No currently-open tenders match the account’s keywords.
All previously-matching tenders have already closed.
There is nothing to retry here — the response is authoritative.