Docs
On this page
Docs/AVM/Batch and Asynchronous Jobs

API Reference · AVM

Batch and Asynchronous Jobs

Use synchronous batches for portfolios that can be completed within one HTTP request. Where enabled, asynchronous jobs support larger workloads and work that must continue after the client disconnects.

Before using a job endpoint, confirm that /v3/valuation-jobs appears in the endpoints returned by GET /v3/releases/current. If it is absent, use a synchronous batch within the published limit.

Choose a Processing Method

WorkloadRecommended operation
One interactive propertySimple or standard single endpoint
A basic portfolio within the published synchronous limitSynchronous batch
A larger detailed portfolio, or work that must survive a disconnectAsynchronous job, where enabled
More than effective job limitSplit into independently idempotent jobs

Your plan or the maximum request-body size may impose a lower limit.

Check limits.synchronous_batch_rows and limits.asynchronous_job_rows in GET /v3/releases/current. Requests exceeding the applicable row or body limit are rejected with HTTP 413. Split large requests into smaller batches or use jobs within their published limits. Synchronous endpoints do not silently change their response into a job response.

Published row limits are not latency guarantees. Many uncached address lookups can make even a smaller batch unsuitable for a synchronous request. See Latency and Throughput for timing guidance and Limits and Safeguards for payload and capacity limits.

Synchronous Batch Request

json
{
  "options": {
    "use_stored_data": false
  },
  "requests": [
    {
      "request_reference": "portfolio-001",
      "property": {
        "valuation_date": "2026-09-08",
        "uprn": "100012345678",
        "postcode": "OX1 1AA",
        "type": "D",
        "subtype": "house_detached",
        "title_tenure": "freehold",
        "building_number_or_name": "14",
        "street": "Station Road"
      },
      "occupancy": {"status": "owner_occupied"},
      "size": {
        "floor_area_m2": 180,
        "bedrooms": 4,
        "living_rooms": 3,
        "storeys": 2
      }
    }
  ]
}

Each row uses the documented single-value request schema. request_reference is optional; the service generates a unique valuation_id for every row.

Shared Options and Property Overrides

Batch-level options apply to every property unless that property explicitly overrides a setting in its own options. Each setting is resolved separately: property override, then batch setting, then the documented default.

For example, with batch options {"include_comparables": true, "comparables_limit": 5}:

Property optionsResult for that property
Omitted, null, or {}Up to five comparables.
{"comparables_limit": 2}Up to two comparables; other batch settings still apply.
{"comparables_limit": 0}An empty comparables list. Zero is not treated as missing.
{"include_comparables": false}No comparables section; other batch settings still apply.
{"include_context_metrics": true}Location context and up to five comparables.

The same precedence applies to context and stored-data enrichment. For example, a property can set use_stored_data to false even when the batch sets it to true. Changing one property never changes the settings for another. Omit an individual option to inherit it; individual option values must not be null. Fewer comparables may be returned if insufficient eligible evidence is available.

These rules apply to synchronous batches, development batches for their supported options, and asynchronous jobs where enabled. Simple endpoints and simple jobs still omit optional supporting evidence. Valuation range and confidence remain part of the core response.

Partial Success

Batch HTTP 200 means the request envelope was processed, not that every row received a value.

json
{
  "status": "partial",
  "summary": {
    "requested": 100,
    "valued": 94,
    "referred": 3,
    "rejected": 2,
    "valuation_failed": 1
  },
  "results": []
}

Inspect the status of every result. HTTP 207 is not used. Results retain input order and can be reconciled by position, valuation_id or the optional customer reference.

An invalid request envelope may be rejected before any rows are processed. Once row processing begins, identity errors, manual referrals and valuation failures are returned against the affected row.

Simple Versus Standard Batch

Use /v3/simple-batch-value for the valuation, range, confidence and input-resolution record. Use /v3/batch-value when you also require comparables or location context. Both endpoints use the same property schema and valuation basis.

Create an Asynchronous Job

bash
curl --silent --show-error \
  -X POST "https://api.valtaic.io/v3/valuation-jobs" \
  -H "Authorization: Bearer $VALTAIC_API_KEY" \
  -H "Content-Type: application/json" \
  --data @job.json | jq

Request fields:

FieldRequiredMeaning
modeNosimple by default; standard adds requested supporting evidence; development uses the development-property contract and requires development access.
requestsYesProperty request objects, up to the current asynchronous_job_rows limit and your plan limit. Use development-property objects for development mode.
optionsNoShared valuation options.
idempotency_keyNoStable customer-defined key, 1-100 characters, [A-Za-z0-9._:-].

Accepted response:

json
{
  "api_version": "v3",
  "job_id": "9c9c4e6b-fdca-4a95-b167-45c6f2dcc761",
  "status": "queued",
  "mode": "simple",
  "release_id": "<immutable-release-id>",
  "request_count": 1000,
  "created_at": "2026-09-08T09:00:00Z",
  "updated_at": "2026-09-08T09:00:00Z",
  "expires_at": "2026-09-15T09:00:00Z",
  "status_url": "/v3/valuation-jobs/9c9c4e6b-fdca-4a95-b167-45c6f2dcc761",
  "results_url": "/v3/valuation-jobs/9c9c4e6b-fdca-4a95-b167-45c6f2dcc761/results"
}

HTTP 202 confirms that the job has been accepted for processing; it does not indicate completion.

New submissions can temporarily return HTTP 503 while the service is preparing the matching valuation worker. Existing job-status and result requests remain available during an admission pause. Wait and retry the same logical submission with the same idempotency key; do not generate another key for a transport retry.

Idempotency

Use an idempotency key for every production job. Good keys identify the logical portfolio snapshot, not a transport attempt:

text
client-portfolio-2026-09-08-v1

Within a tenant:

  • The same key with an identical request body returns the existing job.
  • The same key with a different request body returns HTTP 409.
  • Another tenant may use the same text without causing a collision.

Retry a timed-out submission with the same idempotency key and same body. An identical retry does not reserve another set of valuation units. After the idempotency retention period expires, the old key cannot create a fresh job; use a new key for genuinely new work.

Poll Status

bash
curl --silent --show-error \
  -H "Authorization: Bearer $VALTAIC_API_KEY" \
  "https://api.valtaic.io/v3/valuation-jobs/$JOB_ID" | jq

States:

  • queued: accepted and awaiting processing.
  • running: processing is in progress.
  • completed: results are available.
  • failed: processing ended unsuccessfully; an error object is available.

Use exponential polling up to a reasonable ceiling. Do not poll many times per second.

Retrieve Results

bash
curl --silent --show-error \
  -H "Authorization: Bearer $VALTAIC_API_KEY" \
  "https://api.valtaic.io/v3/valuation-jobs/$JOB_ID/results" | jq

While incomplete, this returns HTTP 202 and Retry-After: 5. At completion:

json
{
  "api_version": "v3",
  "job_id": "9c9c4e6b-fdca-4a95-b167-45c6f2dcc761",
  "status": "completed",
  "release_id": "<immutable-release-id>",
  "result": {
    "api_version": "v3",
    "release_id": "<immutable-release-id>",
    "status": "partial",
    "summary": {},
    "results": []
  }
}

The job remains associated with the valuation release active when it was submitted. A release published while the job is running does not affect its results.

Durability and Retention

Accepted jobs continue after the submitting client disconnects. Job status and results are retained for seven days. Download completed results into your own system before they expire.

Quotas

Each admitted row counts as one valuation unit. A 1,000-row job therefore uses 1,000 monthly valuation units even though it is submitted in a single HTTP request. Submitting the same work more than once without an idempotency key may consume additional quota.

  1. Query current release and limits.
  2. Validate requests and assign optional customer references in your system.
  3. Split work below both row and body-size limits.
  4. Assign one idempotency key per chunk.
  5. Submit jobs and persist job IDs plus release IDs.
  6. Poll with backoff.
  7. Download each result once completed.
  8. Reconcile every row by valuation_id, optional reference and status.
  9. Persist request, result and release together.
  10. Route manual referrals and permanent failures to operations.