Skip to main content
Check the HTTP status and Content-Type before parsing a response. Most V2 failures use the JSON envelope below. Validation uses error.details instead of error.message. Request rate limiting returns plain text. A bulk results response can return HTTP 200 while individual fields have failed.
Route handlers include X-Request-ID; keep it for support. Failures rejected earlier, such as malformed JSON, oversized bodies, or rate limits, may not include that header. An unknown URL uses the server’s ordinary 404 response rather than the V2 JSON envelope.

HTTP error catalog

These are the public codes emitted by the current V2 routes and their processing workflows. Each endpoint links here and lists its additional errors. Do not branch on message text; messages can vary while a code remains the same.

Authentication and request errors

Bulk job errors

A malformed job UUID returns 422 INVALID_REQUEST, not BULK_JOB_NOT_FOUND. Bulk submission validates all fields before acceptance; a 422 creates no job.

Field and application errors

These can occur during a single check, field processing, application-time drift calculation, or as a failed bulk item’s error. Report lookup can also return DUPLICATE_FIELD.

Portal and report errors

Portal website errors are separate from this API catalog. For example, an expired signed link opened in the portal is not an API-key authentication failure.

Capacity and deadline errors

Validation examples

Bulk submission, job status, and results validation return an array in error.details. Other endpoints return flattened error.details.formErrors and error.details.fieldErrors. Validation runs before API-key authentication, so invalid inputs can return 422 even with a missing key.

Missing required bulk group

Omitting provider_group_id from an otherwise valid bulk request returns HTTP 422:

Missing effective product pests

If the second field’s first product has no product pests, field pests, or top-level pest default:
fields[1] means the second field; products[0] means its first product. Set pest at one of those three levels. An empty list does not satisfy the requirement.

A top-level option placed inside a field

Putting include_geometry inside the first field returns:
Move include_geometry to the top level. It applies to all fields. An invalid Idempotency-Key uses the path ["idempotency_key"]; an invalid results page size uses ["limit"].

Non-bulk validation

For example, omit locked when setting an application portal lock:
The application-time drift endpoint validates its body under payload, so its flattened field errors may be grouped under payload.

Conflict and rate-limit examples

A changed request under a reused bulk idempotency key returns HTTP 409:
When the bulk backlog is full, the response is HTTP 429 with JSON:
An API-key or IP request limit instead returns a text body. The retry duration depends on the remaining limit window; 30 below is illustrative:
Check Content-Type before calling your client’s JSON parser. V2 applies per-minute limits to each API key and a shared IP limit. Your quota depends on the service configuration. Polling requests count toward these limits.

Bulk item failures

An accepted job processes fields independently. A results GET can return HTTP 200 and success: true even when an item failed. The example below is one selected item from items[]:
Failed items can contain the field/application codes above, portal-signing errors, deadline/cancellation errors, PROCESSING_FAILED, or ATTEMPTS_EXHAUSTED. PROCESSING_FAILED uses message Field processing failed for unexpected processing failures; its retryable value depends on the cause. The worker retries transient failures up to three total attempts. PROCESSING_CONFLICT, FIELD_CHANGED, APPLICATION_CHANGED, DEADLINE_EXCEEDED, and REQUEST_CANCELLED are retryable. For example, exhausted retries can produce:
retryable: true describes the cause; it does not promise another automatic attempt after the item becomes failed. Wait for a terminal job, inspect failed items, then submit only the fields you need to retry with a new idempotency key. Replaying the original key returns the original job, including its failures. Repeated processing interruptions can exhaust attempts during recovery. The failed item’s error then contains:
Queued items awaiting a retry can retain an error from an earlier attempt; starting the next attempt clears it. Use status to decide whether the item is final. Successful processing still requires inspecting the assessment’s compliance status.

Assessment issue codes

These codes appear in successful response issue lists, such as compliance.issues, drift assessment issues, or runoff-baseline issues. They are not HTTP error codes. A bulk item can be succeeded while its assessment is indeterminate or not_met. For example, these selected fields can appear in an HTTP 200 response:
compliance.version versions the assessment structure, not the API route. Reuse existing soil/product caches. Background enrichment does not rewrite a completed result; resubmit the application to obtain an updated assessment.

Retry safely

  1. Correct 400/401/403/404/413/422 problems before retrying. Resolve identity and idempotency conflicts instead of blindly retrying every 409.
  2. For transient 409/429/502/503 failures, use exponential backoff with jitter. Honor Retry-After when present. A retry header does not make an identity conflict transient.
  3. After a bulk submission timeout, retry the same effective input with the same Idempotency-Key. The first attempt may already have created the job.
  4. After acceptance, poll that job. Fetch every results page and inspect each item’s status. Do not cache bulk status or results; successful responses use Cache-Control: no-store.
  5. After a terminal job, retry failed fields separately with a new key. For single checks, reuse the same provider/account/application identifiers and read the refreshed assessment.
Most error-handler responses with 409, 429, or 503 include Retry-After: 5. A deadline response sent directly by the route can omit it. A missing response or timeout does not establish whether the operation saved changes.