Estimates

Get estimate job status

Retrieves the current status and results of an estimate job. Use this endpoint to poll for job completion if webhook delivery fails.

Flexible ID Lookup: The estimateJobId parameter accepts either:

  • The UUID returned from estimate creation (e.g., e1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c)
  • Your internal estimate ID provided during creation (e.g., EST-12345)

The system will automatically match against both the job ID and external ID fields.

Versioning: Estimates support multiple versions. Each time an estimate is updated/regenerated, a new version is created.

  • Without ?version parameter: Returns the current/latest version
  • With ?version=N parameter: Returns a specific version (e.g., ?version=1 for the original)

Status Values:

  • PROCESSING: Job is being processed
  • COMPLETED: Job finished successfully, results available
  • FAILED: Job failed, error information available

Results on a failed job: result is normally present only for a COMPLETED job. The exception is error.code = MARKUP_GENERATION_FAILED, where the estimate itself succeeded and only its takeoff markup deliverable could not be produced — the result is returned alongside the error, matching the webhook for that job.

get/v1/estimate/{estimateJobId}

Request

  • Base URL: https://api.handoff.ai
  • URL: https://api.handoff.ai/v1/estimate/{estimateJobId}
  • Auth: HTTP bearer

Path parameters

estimateJobIdstring required

Estimate identifier - can be either the UUID job ID or your internal externalId

Example:e1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c

Query parameters

versionstring

Specific version number to retrieve. If omitted, returns the current/latest version.

Example:1

Response

Estimate job status and results

estimateJobIdstring uuid required

Unique identifier for the estimate generation job

externalIdstring

Partner's internal estimate ID provided during job creation

type'MATERIAL_LIST' | 'BLUEPRINT' required

Type of estimate request: 'MATERIAL_LIST' for material lists or 'BLUEPRINT' for blueprints

fileIdsstring[] required

List of file IDs used to generate this estimate (deprecated: use 'files' for full metadata)

addressstring

Address or ZIP code for regional availability and pricing

promptstring

Special instructions and scope of work for the estimate (e.g., 'Create an estimate for framing and painting.')

customerReferencestring

Partner's internal reference/order number for tracking specific customers

callbackUrlstring

Webhook URL for job completion notification

status'PENDING' | 'EXTRACTING' | 'LABELING' | 'AGENTIC_TAKEOFF' | 'INGESTING' | 'PROCESSING' | 'HUMAN_REVIEW' | 'COMPLETED' | 'FAILED' | 'CANCELED' required

Current status. Possible values: PENDING, EXTRACTING, LABELING, AGENTIC_TAKEOFF, INGESTING, PROCESSING, HUMAN_REVIEW, COMPLETED, FAILED, CANCELED

createdAtstring required
estimatedCompletionTimestring
completedAtstring
failedAtstring
humanReviewStartedAtstring

ISO 8601 timestamp of when human review started (if status is HUMAN_REVIEW)

versioninteger

Version number of the estimate being returned (1, 2, 3, ...)

currentVersioninteger

The current/latest version number for this estimate job

metadataobject

Custom key-value pairs for tracking context

Example response

{
  "estimateJobId": "e1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
  "externalId": "EST-12345",
  "type": "MATERIAL_LIST",
  "fileIds": [
    "f1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
    "f2b3c4d5-e6f7-4a8b-9c0d-1e2f3a4b5c6d"
  ],
  "files": [
    {
      "id": "f1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
      "filename": "floor_plan.pdf",
      "contentType": "application/pdf",
      "sizeBytes": 1048576,
      "confidence": "HIGH"
    },
    {
      "id": "f2b3c4d5-e6f7-4a8b-9c0d-1e2f3a4b5c6d",
      "filename": "materials.xlsx",
      "contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      "sizeBytes": 524288,
      "confidence": null
    }
  ],
  "takeoffFiles": [
    {
      "id": "a7c31c2b-9f4e-5d3a-8b1c-2e6f4a5b6c7d",
      "filename": "takeoff-markup.pdf",
      "fileType": "TAKEOFF_MARKUP",
      "contentType": "application/pdf",
      "sizeBytes": 2456789,
      "status": "READY",
      "checksum": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
    }
  ],
  "address": "Austin, TX 78701",
  "prompt": "Create an estimate for framing and painting.",
  "customerReference": "CUST-ORD-789",
  "callbackUrl": "https://partners.example.com/webhooks/estimate",
  "status": "COMPLETED",
  "createdAt": "2025-12-05T14:30:00Z",
  "estimatedCompletionTime": "2025-12-05T14:31:00Z",
  "completedAt": "2025-12-05T14:30:45Z",
  "failedAt": "2025-12-05T14:30:45Z",
  "humanReviewStartedAt": "2025-12-05T14:30:45Z",
  "version": 1,
  "currentVersion": 2,
  "result": {
    "items": [
      {
        "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
        "group": "Framing",
        "productName": "2x6 PT Bottom Plates at First Floor",
        "quantity": 3100,
        "rateAmount": 50,
        "totalAmount": 155000,
        "description": "Pressure treated bottom plates for first floor framing",
        "category": "Material",
        "unit": "LINEAR_FOOT",
        "unitAbbreviation": "LF",
        "currency": "USD",
        "attributes": {
          "wasteFactor": 0.1,
          "location": "First Floor",
          "building": "Main House",
          "categoryName": "Lumber & Composites",
          "categoryCode": "L",
          "extractedLabel": "200 - 2x6 PT Bottom Plates (1234567)",
          "contextualSection": "Framing",
          "partnerItemId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
        },
        "productMatch": {
          "supplier": "Lowe's",
          "productName": "Severe Weather 2-in x 6-in x 8-ft #2 Prime Southern yellow pine Above ground Pressure Treated Lumber",
          "productUrl": "https://www.lowes.com/pd/Severe-Weather-Common-2-in-x-6-in-x-8-ft-Actual-1-5-in-x-5-5-in-x-8-ft-2-Prime-Treated-Lumber/4564606",
          "productBrand": "Severe Weather",
          "attributes": {
            "productId": "4564606",
            "productUnitRatio": {
              "EA": 1,
              "LF": 8
            },
            "conversionRatio": 8,
            "quantitySellableRound": 427,
            "unitSellable": "EA",
            "rateAmountSellable": 3200,
            "totalAmountSellable": 136640,
            "itemNumber": "196037",
            "modelNumber": "OG2P20608-AG",
            "productImageUrl": "https://handoff.ai/exampleimage/4564606/4564606.jpg",
            "partialMatch": true
          }
        },
        "districtAvailability": "in-store"
      }
    ],
    "summary": {
      "description": "This estimate covers first floor framing including walls, headers, and floor joists for a 2,500 sq ft residential addition.",
      "totalItems": 25,
      "matchedItems": 23,
      "unmatchedItems": 2,
      "matchingPercentage": 92,
      "totalAmount": 1550000,
      "currency": "USD"
    },
    "message": "I increased the drywall quantity to 1,200 SF and added two interior doors as requested."
  },
  "error": {
    "code": "ESTIMATE_FAILED",
    "message": "Unable to process estimate"
  },
  "metadata": {
    "source": "takeoff-api",
    "projectId": "proj-123",
    "quantity": 100
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.