Appraisal Host - Appraisal Management Software for AMCs and Lenders

Developer documentation

OpenAPI 3.1 spec

Guide

Appraisal Host APIAuthenticationSandboxOrder lifecycleWebhooksReference notesChangelogSupport

API reference

Every endpointServiceAuthenticationOrder TypesOrdersOrder ActionsRevision RequestsMessagesDocumentsEventsWebhook ConfigurationSandboxNotificationsObjects

API reference

The Appraisal Host API lets a loan origination system, a point of sale, or any ordering platform place appraisal orders with an appraisal management company that runs on Appraisal Host, follow each order through its lifecycle, exchange messages and documents, and receive the finished report package.

One address serves every appraisal management company on the platform. Each credential we issue belongs to one lender account at one company, so the credential itself tells us where the order belongs. You store one base URL and one credential per lender you serve.

Conventions used throughout:

  • JSON request and response bodies, UTF-8.
  • Identifiers are opaque prefixed strings (ord_, doc_, msg_, rr_, evt_, cli_). Treat them as strings of up to 64 characters and do not parse them.
  • Timestamps are ISO-8601 in UTC, for example 2026-09-17T14:32:05Z. Dates without a time are YYYY-MM-DD.
  • Money is a decimal string with a separate currency code, for example "525.00" with "USD". We never send money as a floating point number.
  • Every error shares one body shape: code, message, an optional details array, and a correlation_id you can quote to our integrations team.
  • List endpoints return a data array with page, per_page, total and total_pages. The event feed uses a cursor instead.

The full guide, including sandbox access and webhook verification samples, is published at https://www.appraisalhost.com/developers and this document is downloadable at https://www.appraisalhost.com/developers/spec/openapi.json.

Production

https://api.appraisalhost.com/v1

Sandbox. Access is provisioned on request by our integrations team.

https://sandbox.api.appraisalhost.com/v1

This page is generated from the published contract. The same document is available as a file at /developers/spec/openapi.json for client generation and API tooling.

Service

Liveness check. No credential required.
GET/ping

Liveness check

Returns 200 while the API is serving traffic. No credential is required, and the response never contains account data. Use it in your own monitoring.

Responses

200
The API is serving traffic.
{
  "status": "ok",
  "time": "2026-09-17T14:32:05Z"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Authentication

Exchange your client id and client secret for a short lived bearer token, then send that token on every other call.
POST/oauth/token

Get an access token

Exchange your client id and client secret for a bearer token. The token is opaque, is valid for 60 minutes, and carries the lender scope. Request a new token shortly before the old one expires, or when a call returns 401 with code token_expired. Tokens are not revoked when you request a new one, so a rolling refresh is safe.

This is an OAuth 2.0 client credentials token endpoint. It accepts application/x-www-form-urlencoded, with client_id and client_secret either in the body or in an HTTP Basic header, and it also accepts a JSON body of the same fields. Never place a client secret in a URL or in a query string.

Errors here, and only here, use the RFC 6749 shape (error, error_description) rather than this API's standard error body, so that a standard client library can classify them. Every other endpoint answers with the standard error body.

Request bodyrequired

Accepted content types: application/x-www-form-urlencoded or application/json

FieldTypeDescription
grant_typerequiredstring
client_idrequiredstringThe client id we issued. Always starts with cli_.
client_secretrequiredstringThe client secret we issued. Shown once, at creation. Store it in a secret manager.
scopestringOptional. The only scope in version 1 is lender, which is also the default.

Example request

{
  "grant_type": "client_credentials",
  "client_id": "cli_example_2f8c41",
  "client_secret": "example_secret_do_not_use_9f4b1c77ae"
}

Responses

200
A new access token.
{
  "access_token": "aht_at_7Qk2rX9wTm4ZbN1sV6yH0pL8",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "lender"
}
400
The request is not a valid token request: a missing or unsupported grant_type, or a missing credential. RFC 6749 shape.
Example error body
{
  "error": "invalid_request",
  "error_description": "grant_type must be client_credentials.",
  "correlation_id": "req_01J9Z2A7K3M5P8R1T4W6Y9B2D"
}
401
The client id or client secret is wrong, or the client has been revoked. RFC 6749 shape.
Example error body
{
  "error": "invalid_client",
  "error_description": "The client id or client secret is not valid.",
  "correlation_id": "req_01J9Z2A7K3M5P8R1T4W6Y9B2D"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
GET/account

Read what this credential is for

Returns the lender account and the appraisal management company this credential belongs to, the environment it works in, the scopes it carries and its rate limit.

Call it at start-up for every credential you hold, and check lender.id and lender.name against your own configuration before you place an order with it. A credential mapped to the wrong lender would place that lender's borrower on another lender's account, and this is the check that catches it.

Responses

200
The account this credential belongs to.
{
  "client_id": "cli_example_2f8c41",
  "environment": "production",
  "lender": {
    "id": "len_4WQ2H8ZKPB31",
    "name": "Example Mortgage Group"
  },
  "company": {
    "id": "cmp_7YT5M2XRND94",
    "name": "Example Appraisal Management"
  },
  "scopes": [
    "lender"
  ],
  "rate_limit": {
    "requests_per_minute": 600
  }
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Order Types

The products a lender may order from its appraisal management company, and the report format each product is delivered in. Read this before you place an order: it tells you which loan types and add-ons apply and which documents to expect back.
GET/order-types

List the products this lender may order

Returns the order types available to your lender account, the report format each one is delivered in, and, for products on the current report standard, the loan types and add-ons that may be attached.

Read this endpoint before you place an order. It is the only place that tells you, in advance, which documents will come back and which loan_type_code and add_on_codes values the product accepts. Codes are stable for each appraisal management company; names are display text and may be reworded. The list is ordered by code, ascending.

A product this lender is not entitled to order does not appear here at all. A product the company has withdrawn appears with active: false and cannot be ordered.

Parameters

NameInTypeDescription
pagequeryintegerThe page to return, starting at 1.
per_pagequeryintegerHow many items to return per page, from 1 to 100.
has_aduquerybooleanWhich add-ons to list. The default, false, lists the add-ons that apply to a property without an accessory dwelling unit. True lists those same add-ons plus the ones that apply only when the property has one.
report_formatquerystring enumReturn only order types delivered in this report format.

Responses

200
The order types available to your lender account.
{
  "data": [
    {
      "code": "SFR-1004-36",
      "name": "Single Family Residential, current report standard",
      "report_format": "uad_3_6",
      "appraiser_certification": "none",
      "active": true,
      "loan_types": [
        {
          "code": "conventional",
          "name": "Conventional"
        },
        {
          "code": "conventional_new_construction",
          "name": "Conventional, New Construction"
        },
        {
          "code": "va",
          "name": "VA"
        }
      ],
      "add_ons": [
        {
          "code": "rent_schedule",
          "name": "Rent Schedule"
        },
        {
          "code": "operating_income_statement",
          "name": "Operating Income Statement"
        }
      ],
      "loan_purposes": [],
      "property_types": [
        "single_family",
        "condominium",
        "townhouse",
        "two_to_four_unit_property"
      ]
    },
    {
      "code": "SFR-1004-FHA",
      "name": "Single Family Residential, FHA",
      "report_format": "uad_3_6",
      "appraiser_certification": "fha_required",
      "active": true,
      "loan_types": [
        {
          "code": "fha",
          "name": "FHA"
        }
      ],
      "add_ons": [],
      "loan_purposes": [],
      "property_types": [
        "single_family",
        "condominium",
        "townhouse"
      ]
    },
    {
      "code": "DRIVEBY-2055",
      "name": "Exterior Only Inspection",
      "report_format": "uad_2_6",
      "appraiser_certification": "none",
      "active": true,
      "loan_types": [],
      "add_ons": [
        {
          "code": "rent_schedule",
          "name": "Rent Schedule"
        }
      ],
      "loan_purposes": [
        "purchase"
      ],
      "property_types": []
    }
  ],
  "page": 1,
  "per_page": 25,
  "total": 3,
  "total_pages": 1
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Orders

Create, read, list and amend orders.
GET/orders

List orders

Returns the orders that belong to your lender account, ordered by created_at descending with id as the tie break.

Filter by one or more status codes, and by updated_since to poll for change. updated_since is inclusive to the second, so overlap your windows by a second or two rather than trusting exact boundaries. Webhooks remain the primary way to learn about change: this endpoint is for reconciliation and for catching up.

Page numbers walk a collection that can change while you read it, so an order touched between your first page and your last can move. Walk every page quickly, then run the same window again and compare the two runs: when they agree, nothing moved underneath you.

Parameters

NameInTypeDescription
pagequeryintegerThe page to return, starting at 1.
per_pagequeryintegerHow many items to return per page, from 1 to 100.
statusquerystringOne or more status codes, comma separated. See the status catalog in the schema OrderStatusCode.
updated_sincequerystring (date-time)Return only orders changed at or after this instant. updated_at moves when anything you can see on the order changes: its status, its dates, its fee, its documents, its messages and its own fields.
order_numberquerystringReturn the order carrying this order number from the appraisal management company.
lender_referencequerystringReturn orders carrying this reference of yours.

Responses

200
A page of orders.
{
  "data": [
    {
      "id": "ord_9TBK4C2QFA7M",
      "order_number": "2026-1043",
      "lender_reference": "LN-2026-88421",
      "status": {
        "code": "appraiser_assigned",
        "label": "Appraiser Assigned",
        "changed_at": "2026-09-18T13:04:11Z"
      },
      "order_type": {
        "code": "SFR-1004-36",
        "name": "Single Family Residential, current report standard",
        "report_format": "uad_3_6",
        "appraiser_certification": "none"
      },
      "property_address_summary": "100 Example Avenue, Springfield, IL 62701",
      "dates": {
        "created_at": "2026-09-17T14:32:05Z",
        "updated_at": "2026-09-18T13:04:11Z",
        "due_date": "2026-10-02",
        "appointment_at": null,
        "completed_at": null
      }
    }
  ],
  "page": 1,
  "per_page": 25,
  "total": 1,
  "total_pages": 1
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
POST/orders

Place an order

Places a new appraisal order for your lender account at its appraisal management company.

Send order_type_code from GET /order-types. For a product on the current report standard, also send loan_type_code, and add_on_codes when you need them: both are validated against the product, and an unknown or inapplicable code is refused with 422 rather than being guessed at.

property.postal_code is required. City, state and county are filled in from the postal code when you leave them out.

Always send an Idempotency-Key. We keep the key for 24 hours: a repeat of the same key with the same body returns the original order instead of creating a second one, and a repeat with a different body is refused with 409 and code idempotency_key_reused.

A create returns 201 and the order. An order we can place straight away is at new and stays there until the appraisal management company assigns an appraiser. An order that needs a review by the company first, for example an unusual product, loan type or property, is at pending_review and moves to new when the company places it. Both are normal, and you will see order.status_changed when the order moves on. A request we can refuse deterministically, such as an unknown code or a code that does not apply to the product, is refused with 422 instead and no order is created.

We never accept card details. API ordering requires a lender account the appraisal management company invoices. An account that pays for each order by card is refused with 403 and code account_not_billable: ask the company to put the account on invoicing first.

Parameters

NameInTypeDescription
Idempotency-KeyheaderstringA unique key of your own, up to 128 characters, that makes this create safe to retry. We remember the key and its result for 24 hours. A key is scoped to your client credential and to this endpoint: the same key sent by another credential is a different key. A repeat with the same key and the same body returns the original order with the original 201. A repeat with the same key and a different body is refused with 409 and code idempotency_key_reused.

Request bodyrequired

Content type: application/json

FieldTypeDescription
order_type_coderequiredstringThe product to order, from GET /order-types.
loan_type_codestring or nullThe loan type tier, from the product's loan_types. Required when the product lists loan types. An unknown or inapplicable code is refused with 422 rather than being guessed at.
add_on_codesarray of stringAdd-ons to attach, from the product's add_ons.
due_daterequiredstring (date)The date the lender needs the report by. The appraisal management company confirms or adjusts it.
lender_referencestring or nullYour own reference for this order. We store it and return it, and you can search on it.
rushboolean
complexboolean
ruralboolean
priorityboolean
certified_appraiser_requiredboolean
appraiser_instructionsstring or nullAccess instructions and anything else the appraiser needs to know.
loanrequiredLoanCreateThe loan the appraisal supports.
propertyrequiredPropertyCreateThe property to be appraised.
borrowersrequiredarray of BorrowerOrCoBorrowerThe borrower, and a co-borrower when there is one.
partiesPartiesOther people involved in the order.
notesarray of Note
documentsarray of InlineDocumentSupporting documents to attach at create, base64 encoded. Prefer POST /orders/{order_id}/documents for anything over a megabyte or two.

Example: A product on the current report standard, with a loan type and an add-on

{
  "order_type_code": "SFR-1004-36",
  "loan_type_code": "conventional",
  "add_on_codes": [
    "rent_schedule"
  ],
  "due_date": "2026-10-02",
  "rush": false,
  "complex": false,
  "rural": false,
  "priority": false,
  "certified_appraiser_required": true,
  "appraiser_instructions": "Gate code 4417. Call the listing agent for access.",
  "lender_reference": "LN-2026-88421",
  "loan": {
    "purpose": "purchase",
    "number": "88421",
    "client": "Example Mortgage Group",
    "investor": "Example Investor Trust",
    "purchase_price": "415000.00",
    "currency": "USD"
  },
  "property": {
    "address": {
      "street": "100 Example Avenue",
      "unit": "Unit 2",
      "city": "Springfield",
      "state": "IL",
      "postal_code": "62701",
      "county": "Sangamon"
    },
    "type": "single_family",
    "occupancy": "primary_residence",
    "has_adu": true
  },
  "borrowers": [
    {
      "role": "borrower",
      "first_name": "Sample",
      "last_name": "Borrower",
      "receives_report": false,
      "receives_status_updates": true,
      "address": {
        "street": "300 Example Street",
        "city": "Springfield",
        "state": "IL",
        "postal_code": "62703"
      },
      "contacts": [
        {
          "type": "email",
          "role": "home",
          "value": "sample.borrower@example.com"
        },
        {
          "type": "phone",
          "role": "cell",
          "value": "+1-217-555-0142"
        }
      ]
    },
    {
      "role": "co_borrower",
      "first_name": "Second",
      "last_name": "Borrower",
      "contacts": [
        {
          "type": "phone",
          "role": "work",
          "value": "+1-217-555-0143"
        }
      ]
    }
  ],
  "parties": {
    "real_estate_agent": {
      "first_name": "Sample",
      "last_name": "Agent",
      "contacts": [
        {
          "type": "phone",
          "role": "cell",
          "value": "+1-217-555-0190"
        }
      ]
    },
    "additional_contacts": [
      {
        "purpose": "status",
        "name": "Processing Desk",
        "email": "processing@example.com"
      },
      {
        "purpose": "report",
        "name": "Closing Desk",
        "email": "closing@example.com"
      }
    ]
  },
  "notes": [
    {
      "type": "order",
      "text": "Borrower prefers a morning appointment."
    },
    {
      "type": "appointment",
      "text": "Dog on the property, please call ahead."
    }
  ]
}

Example: A product on the prior report standard, minimum fields

{
  "order_type_code": "DRIVEBY-2055",
  "due_date": "2026-09-30",
  "loan": {
    "purpose": "refinance",
    "number": "88422"
  },
  "property": {
    "address": {
      "street": "200 Example Lane",
      "postal_code": "62704"
    },
    "type": "condominium",
    "occupancy": "second_home"
  },
  "borrowers": [
    {
      "role": "borrower",
      "first_name": "Example",
      "last_name": "Borrower",
      "contacts": [
        {
          "type": "email",
          "role": "home",
          "value": "example.borrower@example.com"
        }
      ]
    }
  ]
}

Responses

201
The order was created.
{
  "id": "ord_9TBK4C2QFA7M",
  "order_number": "2026-1043",
  "lender_reference": "LN-2026-88421",
  "status": {
    "code": "new",
    "label": "New Order",
    "changed_at": "2026-09-17T14:32:05Z"
  },
  "order_type": {
    "code": "SFR-1004-36",
    "name": "Single Family Residential, current report standard",
    "report_format": "uad_3_6",
    "appraiser_certification": "none"
  },
  "loan": {
    "purpose": "purchase",
    "purpose_other": null,
    "number": "88421",
    "client": "Example Mortgage Group",
    "investor": "Example Investor Trust",
    "agency_case_number": null,
    "fha_case_number": null,
    "purchase_price": "415000.00",
    "currency": "USD",
    "loan_type": {
      "code": "conventional",
      "name": "Conventional"
    },
    "add_ons": [
      {
        "code": "rent_schedule",
        "name": "Rent Schedule"
      }
    ]
  },
  "property": {
    "address": {
      "street": "100 Example Avenue",
      "unit": "Unit 2",
      "city": "Springfield",
      "state": "IL",
      "postal_code": "62701",
      "county": "Sangamon"
    },
    "type": "single_family",
    "occupancy": "primary_residence",
    "has_adu": true
  },
  "borrowers": [
    {
      "role": "borrower",
      "first_name": "Sample",
      "last_name": "Borrower",
      "receives_report": false,
      "receives_status_updates": true,
      "address": {
        "street": "300 Example Street",
        "city": "Springfield",
        "state": "IL",
        "postal_code": "62703",
        "county": "Sangamon"
      },
      "contacts": [
        {
          "type": "email",
          "role": "home",
          "value": "sample.borrower@example.com"
        },
        {
          "type": "phone",
          "role": "cell",
          "value": "+1-217-555-0142"
        }
      ]
    },
    {
      "role": "co_borrower",
      "first_name": "Second",
      "last_name": "Borrower",
      "receives_report": false,
      "receives_status_updates": false,
      "address": null,
      "contacts": [
        {
          "type": "phone",
          "role": "work",
          "value": "+1-217-555-0143"
        }
      ]
    }
  ],
  "parties": {
    "real_estate_agent": {
      "first_name": "Sample",
      "last_name": "Agent",
      "contacts": [
        {
          "type": "phone",
          "role": "cell",
          "value": "+1-217-555-0190"
        }
      ]
    },
    "additional_contacts": [
      {
        "purpose": "status",
        "name": "Processing Desk",
        "email": "processing@example.com"
      },
      {
        "purpose": "report",
        "name": "Closing Desk",
        "email": "closing@example.com"
      }
    ]
  },
  "notes": [
    {
      "type": "order",
      "text": "Borrower prefers a morning appointment."
    },
    {
      "type": "appointment",
      "text": "Dog on the property, please call ahead."
    }
  ],
  "flags": {
    "rush": false,
    "complex": false,
    "rural": false,
    "priority": false,
    "certified_appraiser_required": true
  },
  "appraiser_instructions": "Gate code 4417. Call the listing agent for access.",
  "appraiser": null,
  "dates": {
    "created_at": "2026-09-17T14:32:05Z",
    "updated_at": "2026-09-17T14:32:05Z",
    "due_date": "2026-10-02",
    "appointment_at": null,
    "completed_at": null
  },
  "fees": {
    "appraisal_fee": "525.00",
    "currency": "USD"
  },
  "documents": []
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but this account cannot place orders through the API: it pays for each order by card rather than being invoiced.
Example error body
{
  "code": "account_not_billable",
  "message": "This lender account is billed per order by card and cannot order through the API.",
  "correlation_id": "req_01J9Z2CF8H4N7Q0S3V6X9A2C5"
}
409
The Idempotency-Key was already used with a different body.
Example error body
{
  "code": "idempotency_key_reused",
  "message": "This Idempotency-Key was used for a different request within the last 24 hours.",
  "correlation_id": "req_01J9Z2CF8H4N7Q0S3V6X9A2C5"
}
413
The upload is larger than 25 MB.
Example error body
{
  "code": "payload_too_large",
  "message": "The file is larger than the 25 MB limit.",
  "correlation_id": "req_01J9Z45Y8B1D4F7H0K3M6P9R"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
GET/orders/{order_id}

Read an order

Returns the full order, its current status, the documents on it, and the fee the lender is charged. You see exactly what the lender sees in the portal, with the same status wording, and nothing more.

Responses

200
The order.
{
  "id": "ord_9TBK4C2QFA7M",
  "order_number": "2026-1043",
  "lender_reference": "LN-2026-88421",
  "status": {
    "code": "report_complete",
    "label": "Report Complete",
    "changed_at": "2026-09-29T18:12:44Z"
  },
  "order_type": {
    "code": "SFR-1004-36",
    "name": "Single Family Residential, current report standard",
    "report_format": "uad_3_6",
    "appraiser_certification": "none"
  },
  "loan": {
    "purpose": "purchase",
    "purpose_other": null,
    "number": "88421",
    "client": "Example Mortgage Group",
    "investor": "Example Investor Trust",
    "agency_case_number": null,
    "fha_case_number": null,
    "purchase_price": "415000.00",
    "currency": "USD",
    "loan_type": {
      "code": "conventional",
      "name": "Conventional"
    },
    "add_ons": [
      {
        "code": "rent_schedule",
        "name": "Rent Schedule"
      }
    ]
  },
  "property": {
    "address": {
      "street": "100 Example Avenue",
      "unit": "Unit 2",
      "city": "Springfield",
      "state": "IL",
      "postal_code": "62701",
      "county": "Sangamon"
    },
    "type": "single_family",
    "occupancy": "primary_residence",
    "has_adu": true
  },
  "borrowers": [
    {
      "role": "borrower",
      "first_name": "Sample",
      "last_name": "Borrower",
      "receives_report": false,
      "receives_status_updates": true,
      "address": null,
      "contacts": [
        {
          "type": "email",
          "role": "home",
          "value": "sample.borrower@example.com"
        }
      ]
    }
  ],
  "parties": {
    "real_estate_agent": null,
    "additional_contacts": []
  },
  "notes": [
    {
      "type": "order",
      "text": "Borrower prefers a morning appointment."
    }
  ],
  "flags": {
    "rush": false,
    "complex": false,
    "rural": false,
    "priority": false,
    "certified_appraiser_required": true
  },
  "appraiser_instructions": "Gate code 4417. Call the listing agent for access.",
  "appraiser": {
    "name": "J. Marsh"
  },
  "dates": {
    "created_at": "2026-09-17T14:32:05Z",
    "updated_at": "2026-09-29T18:12:44Z",
    "due_date": "2026-10-02",
    "appointment_at": "2026-09-22T15:00:00Z",
    "completed_at": "2026-09-29T18:12:44Z"
  },
  "fees": {
    "appraisal_fee": "525.00",
    "currency": "USD"
  },
  "documents": [
    {
      "id": "doc_3XH8M1PLQW60",
      "kind": "report_pdf",
      "filename": "report_2026-1043.pdf",
      "content_type": "application/pdf",
      "size_bytes": 2841773,
      "created_at": "2026-09-29T18:12:44Z"
    },
    {
      "id": "doc_5RJ2N7VKTB41",
      "kind": "report_data",
      "filename": "report_2026-1043.zip",
      "content_type": "application/zip",
      "size_bytes": 1044210,
      "created_at": "2026-09-29T18:12:44Z"
    },
    {
      "id": "doc_8QL4P9WMYC72",
      "kind": "invoice",
      "filename": "invoice_2026-1043.pdf",
      "content_type": "application/pdf",
      "size_bytes": 88120,
      "created_at": "2026-09-29T18:12:45Z"
    }
  ]
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
PATCH/orders/{order_id}

Amend an order

Amends the parts of an open order a lender may change: the loan number and your own reference, the contacts and parties, the notes, the appraiser instructions, and a request to move the due date.

A due date you send is a REQUEST. The appraisal management company confirms or adjusts it, and the date on the order changes only when the company accepts it. Watch order.due_date_changed for the outcome.

The property, the borrower names, the order type, the loan type and the add-ons cannot be changed once an order exists. Cancel the order and place a new one instead. Amending a closed order is refused with 409.

Some companies do not let a lender amend an order at all. Then the call is refused with 403 and code action_not_permitted_for_client, and the way to ask is a message on the order.

Request bodyrequired

Content type: application/json

FieldTypeDescription
lender_referencestring or null
due_datestring (date)A REQUEST to move the due date. The date changes only when the appraisal management company accepts it.
appraiser_instructionsstring or null
loanobjectOnly the loan number, the client and the investor may be changed.
borrower_contactsarray of ContactReplaces the borrower's contact list. Names and the property cannot be changed.
partiesPartiesOther people involved in the order.
notesarray of NoteNotes to add to the order. An order carries one note of each type, and what you send is added to the note of that type rather than replacing it. Nothing already on the order is removed.

Example request

{
  "lender_reference": "LN-2026-88421-R2",
  "loan": {
    "number": "88421-A"
  },
  "due_date": "2026-10-06",
  "appraiser_instructions": "New gate code 8891.",
  "notes": [
    {
      "type": "appointment",
      "text": "Borrower now prefers afternoons."
    }
  ],
  "parties": {
    "additional_contacts": [
      {
        "purpose": "status",
        "name": "Processing Desk",
        "email": "processing2@example.com"
      }
    ]
  }
}

Responses

200
The amended order.
{
  "id": "ord_9TBK4C2QFA7M",
  "order_number": "2026-1043",
  "lender_reference": "LN-2026-88421-R2",
  "status": {
    "code": "appraiser_assigned",
    "label": "Appraiser Assigned",
    "changed_at": "2026-09-18T13:04:11Z"
  },
  "order_type": {
    "code": "SFR-1004-36",
    "name": "Single Family Residential, current report standard",
    "report_format": "uad_3_6",
    "appraiser_certification": "none"
  },
  "loan": {
    "purpose": "purchase",
    "purpose_other": null,
    "number": "88421-A",
    "client": "Example Mortgage Group",
    "investor": "Example Investor Trust",
    "agency_case_number": null,
    "fha_case_number": null,
    "purchase_price": "415000.00",
    "currency": "USD",
    "loan_type": {
      "code": "conventional",
      "name": "Conventional"
    },
    "add_ons": []
  },
  "property": {
    "address": {
      "street": "100 Example Avenue",
      "unit": "Unit 2",
      "city": "Springfield",
      "state": "IL",
      "postal_code": "62701",
      "county": "Sangamon"
    },
    "type": "single_family",
    "occupancy": "primary_residence",
    "has_adu": true
  },
  "borrowers": [],
  "parties": {
    "real_estate_agent": null,
    "additional_contacts": [
      {
        "purpose": "status",
        "name": "Processing Desk",
        "email": "processing2@example.com"
      }
    ]
  },
  "notes": [
    {
      "type": "appointment",
      "text": "Borrower now prefers afternoons."
    }
  ],
  "flags": {
    "rush": false,
    "complex": false,
    "rural": false,
    "priority": false,
    "certified_appraiser_required": true
  },
  "appraiser_instructions": "New gate code 8891.",
  "appraiser": {
    "name": "J. Marsh"
  },
  "dates": {
    "created_at": "2026-09-17T14:32:05Z",
    "updated_at": "2026-09-19T09:15:00Z",
    "due_date": "2026-10-02",
    "appointment_at": null,
    "completed_at": null
  },
  "fees": {
    "appraisal_fee": "525.00",
    "currency": "USD"
  },
  "documents": []
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
409
The request is well formed but conflicts with the order's current state: an action the status does not allow, an amendment to a closed order, or a reused idempotency key.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "A closed order cannot be amended.",
  "current_status": "cancelled",
  "details": [
    {
      "field": "status",
      "code": "current_status",
      "value": "cancelled",
      "message": "The order has been cancelled."
    }
  ],
  "correlation_id": "req_01J9Z44W6Y9B2D5F8H1K4M7P"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Order Actions

Hold, resume and cancel. These are the rules this interface enforces, and an action the order's current status does not allow returns 409.
POST/orders/{order_id}/hold

Place an order on hold

Puts an open order on hold and stands the appraiser down. The appraiser is remembered, so resuming puts the order back where it was.

A hold is allowed while the order is open, is not already on hold, and no report has been delivered. It is refused with 409 when the report has been delivered (report_complete, revised_report_complete), a correction is open (revision_requested), the order is cancelled, or it is already on hold.

Send a reason: the appraisal management company and the appraiser both see it.

Request body

Content type: application/json

FieldTypeDescription
reasonstring

Example request

{
  "reason": "Borrower is renegotiating the purchase price."
}

Responses

200
The order is on hold.
{
  "id": "ord_9TBK4C2QFA7M",
  "order_number": "2026-1043",
  "status": {
    "code": "on_hold",
    "label": "On Hold",
    "changed_at": "2026-09-19T11:02:00Z"
  },
  "previous_status": {
    "code": "appraiser_assigned",
    "label": "Appraiser Assigned"
  }
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
409
The order's current status does not allow a hold.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "An order with a delivered report cannot be placed on hold.",
  "current_status": "report_complete",
  "details": [
    {
      "field": "status",
      "code": "current_status",
      "value": "report_complete",
      "message": "The report has already been delivered."
    }
  ],
  "correlation_id": "req_01J9Z3B2D5F8H1K4M7P0R3T6"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
POST/orders/{order_id}/resume

Take an order off hold

Returns an order from hold to the point it had reached, and puts the remembered appraiser back on it. A resume is allowed while the order is on hold; any other status is refused with 409.

The order comes back at off_hold, which is transitional: it moves on to its working status shortly afterwards, so read the order again rather than treating off_hold as a resting state.

Request body

Content type: application/json

FieldTypeDescription
reasonstring

Example request

{
  "reason": "Purchase price agreed, please proceed."
}

Responses

200
The order has resumed.
{
  "id": "ord_9TBK4C2QFA7M",
  "order_number": "2026-1043",
  "status": {
    "code": "off_hold",
    "label": "Off Hold",
    "changed_at": "2026-09-22T08:40:12Z"
  },
  "previous_status": {
    "code": "on_hold",
    "label": "On Hold"
  }
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
409
The order is not on hold.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "Only an order that is on hold can be resumed.",
  "current_status": "appraiser_assigned",
  "details": [
    {
      "field": "status",
      "code": "current_status",
      "value": "appraiser_assigned",
      "message": "The order is not on hold."
    }
  ],
  "correlation_id": "req_01J9Z3C4F7H0K3M6P9R2T5W8"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
POST/orders/{order_id}/cancel

Cancel an order

Cancels an open order. A cancellation is allowed while the order is open and no report has been delivered. It is refused with 409 when the report has been delivered, a correction is open, or the order is already cancelled. A held order must be resumed first.

Some companies do not allow a lender to cancel at all. In that case the call is refused with 403 and code action_not_permitted_for_client, and the way to ask is a message on the order.

Request body

Content type: application/json

FieldTypeDescription
reasonstring

Example request

{
  "reason": "Loan withdrawn by the borrower."
}

Responses

200
The order is cancelled.
{
  "id": "ord_9TBK4C2QFA7M",
  "order_number": "2026-1043",
  "status": {
    "code": "cancelled",
    "label": "Order Cancelled",
    "changed_at": "2026-09-20T16:22:31Z"
  },
  "previous_status": {
    "code": "appointment_scheduled",
    "label": "Appointment Scheduled"
  }
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
409
The order's current status does not allow a cancellation.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "An order with a delivered report cannot be cancelled.",
  "current_status": "report_complete",
  "details": [
    {
      "field": "status",
      "code": "current_status",
      "value": "report_complete",
      "message": "The report has already been delivered."
    }
  ],
  "correlation_id": "req_01J9Z3D6H9K2M5P8R1T4W7Y0"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Revision Requests

Ask for a correction to a delivered report, or request a reconsideration of value, and read the company's responses.
GET/orders/{order_id}/revision-requests

List the revision requests on an order

Returns every revision request on the order, ordered by created_at descending with id as the tie break, with the company's responses and any documents attached on either side.

Parameters

NameInTypeDescription
pagequeryintegerThe page to return, starting at 1.
per_pagequeryintegerHow many items to return per page, from 1 to 100.

Responses

200
A page of revision requests.
{
  "data": [
    {
      "id": "rr_6PD3K8YWQN25",
      "order_id": "ord_9TBK4C2QFA7M",
      "kind": "reconsideration_of_value",
      "status": "accepted",
      "reason": "Three closed sales within 0.4 miles support a higher value.",
      "acknowledgements": {
        "prior_appraisal_provided": false,
        "comparable_sales_provided": true
      },
      "documents": [],
      "responses": [
        {
          "id": "msg_4NF9R2XWTD86",
          "created_at": "2026-09-30T15:41:00Z",
          "author": {
            "type": "manager",
            "name": "Order Desk"
          },
          "message": "Sent to the appraiser for review. Revised report expected within two business days."
        }
      ],
      "created_at": "2026-09-30T10:04:18Z",
      "updated_at": "2026-09-30T15:41:00Z"
    }
  ],
  "page": 1,
  "per_page": 25,
  "total": 1,
  "total_pages": 1
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
POST/orders/{order_id}/revision-requests

Request a correction or a reconsideration of value

Opens a revision request against a delivered report.

Two kinds are accepted. A correction asks the appraiser to fix or clarify something in the report. A reconsideration_of_value asks the appraiser to reconsider the opinion of value, and requires at least one acknowledgement: that a prior appraisal was provided, or that comparable sales were provided. Attach the sales or the prior report with POST /orders/{order_id}/documents before you open the request, or send them inline.

A request is accepted while the order is at report_complete, revised_report_complete, revision_requested, reconsideration_requested or cancelled. In any other status it is refused with 409.

We fill the rest of the record the appraisal management company needs from the order and your credential. If the order has no loan number, send loan.number on the order first.

The appraisal management company may review the request before it reaches the appraiser. A request therefore starts at submitted and moves to accepted or declined. Watch order.revision_requested and order.revision_responded.

Request bodyrequired

Content type: application/json

FieldTypeDescription
kindrequiredstring enumcorrection asks the appraiser to fix or clarify the report. reconsideration_of_value asks the appraiser to reconsider the opinion of value and requires at least one acknowledgement.One of: correction, reconsideration_of_value
reasonrequiredstringWhat needs to change, and why.
acknowledgementsRevisionAcknowledgementsRequired on a reconsideration of value. At least one must be true, or the request is refused with 422.
document_idsarray of stringDocuments already uploaded to this order that support the request.
documentsarray of InlineDocumentDocuments to attach inline instead of uploading first.

Example: A correction

{
  "kind": "correction",
  "reason": "The gross living area on page 2 does not match the sketch."
}

Example: A reconsideration of value with acknowledgements

{
  "kind": "reconsideration_of_value",
  "reason": "Three closed sales within 0.4 miles support a higher value.",
  "acknowledgements": {
    "prior_appraisal_provided": false,
    "comparable_sales_provided": true
  },
  "document_ids": [
    "doc_2KM7Q0VZTC93"
  ]
}

Responses

201
The revision request was opened.
{
  "id": "rr_6PD3K8YWQN25",
  "order_id": "ord_9TBK4C2QFA7M",
  "kind": "reconsideration_of_value",
  "status": "submitted",
  "reason": "Three closed sales within 0.4 miles support a higher value.",
  "acknowledgements": {
    "prior_appraisal_provided": false,
    "comparable_sales_provided": true
  },
  "documents": [
    {
      "id": "doc_2KM7Q0VZTC93",
      "kind": "supporting",
      "filename": "comparable_sales.pdf",
      "content_type": "application/pdf",
      "size_bytes": 412998,
      "created_at": "2026-09-30T10:02:00Z"
    }
  ],
  "responses": [],
  "created_at": "2026-09-30T10:04:18Z",
  "updated_at": "2026-09-30T10:04:18Z"
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
409
The order's current status does not allow a revision request.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "A revision request can be opened only once a report has been delivered.",
  "current_status": "appraiser_assigned",
  "details": [
    {
      "field": "status",
      "code": "current_status",
      "value": "appraiser_assigned",
      "message": "No report has been delivered on this order yet."
    }
  ],
  "correlation_id": "req_01J9Z3F8K1M4P7R0T3W6Y9B2"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Messages

Exchange messages with the appraisal management company, and with the appraiser when the company allows it.
GET/orders/{order_id}/messages

Read the message thread on an order

Returns the messages on the order that the lender is party to, ordered by created_at ascending, with their attachments. Internal notes between the company and the appraiser are not included: you see the thread the lender sees in the portal.

Parameters

NameInTypeDescription
pagequeryintegerThe page to return, starting at 1.
per_pagequeryintegerHow many items to return per page, from 1 to 100.

Responses

200
A page of messages.
{
  "data": [
    {
      "id": "msg_7SG1T4ZXUE07",
      "order_id": "ord_9TBK4C2QFA7M",
      "recipient": "manager",
      "subject": "Access arrangements",
      "body": "The listing agent will meet the appraiser on site.",
      "author": {
        "type": "lender",
        "name": "Example Mortgage Group"
      },
      "attachments": [],
      "created_at": "2026-09-18T15:10:00Z"
    },
    {
      "id": "msg_8TH2U5AYVF18",
      "order_id": "ord_9TBK4C2QFA7M",
      "recipient": "lender",
      "subject": "Access arrangements",
      "body": "Understood. The appraiser will call the agent to confirm.",
      "author": {
        "type": "manager",
        "name": "Order Desk"
      },
      "attachments": [],
      "created_at": "2026-09-18T16:02:00Z"
    }
  ],
  "page": 1,
  "per_page": 25,
  "total": 2,
  "total_pages": 1
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
POST/orders/{order_id}/messages

Post a message on an order

Sends a message to the appraisal management company, or to the appraiser when the company allows direct contact. recipient must be manager or appraiser; a company that keeps appraiser contact in its own hands refuses appraiser with 422 and code recipient_not_allowed.

Attach a document by uploading it first and quoting its id, or send the message on its own.

Request bodyrequired

Content type: application/json

FieldTypeDescription
recipientrequiredstring enumWho the message is for. A company that keeps appraiser contact in its own hands refuses appraiser with 422 and code recipient_not_allowed.One of: manager, appraiser
subjectstring or null
bodyrequiredstring
document_idsarray of stringDocuments already uploaded to this order to attach.

Example request

{
  "recipient": "manager",
  "subject": "Access arrangements",
  "body": "The listing agent will meet the appraiser on site.",
  "document_ids": []
}

Responses

201
The message was posted.
{
  "id": "msg_7SG1T4ZXUE07",
  "order_id": "ord_9TBK4C2QFA7M",
  "recipient": "manager",
  "subject": "Access arrangements",
  "body": "The listing agent will meet the appraiser on site.",
  "author": {
    "type": "lender",
    "name": "Example Mortgage Group"
  },
  "attachments": [],
  "created_at": "2026-09-18T15:10:00Z"
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
409
The request is well formed but conflicts with the order's current state: an action the status does not allow, an amendment to a closed order, or a reused idempotency key.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "A closed order cannot be amended.",
  "current_status": "cancelled",
  "details": [
    {
      "field": "status",
      "code": "current_status",
      "value": "cancelled",
      "message": "The order has been cancelled."
    }
  ],
  "correlation_id": "req_01J9Z44W6Y9B2D5F8H1K4M7P"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Documents

Upload supporting documents, list the documents on an order, and download a delivered document through a signed link.
GET/orders/{order_id}/documents

List the documents on an order

Returns every document on the order that the lender may see, ordered by created_at descending with id as the tie break, as summaries without a download link. Ask for a link one document at a time with GET /documents/{document_id}, so that links are short lived and are only minted when you are about to use them.

Which documents arrive depends on the product's report format. A product on the prior report standard delivers the report as a PDF plus the report data as an XML file. A product on the current standard delivers the report as a PDF plus the report data as a package in ZIP form. In both cases the invoice, the certificates and any other delivery document are separate files: the package never contains them.

Parameters

NameInTypeDescription
pagequeryintegerThe page to return, starting at 1.
per_pagequeryintegerHow many items to return per page, from 1 to 100.
kindquerystring enumReturn only documents of this kind.

Responses

200
A page of document summaries.
{
  "data": [
    {
      "id": "doc_3XH8M1PLQW60",
      "kind": "report_pdf",
      "filename": "report_2026-1043.pdf",
      "content_type": "application/pdf",
      "size_bytes": 2841773,
      "created_at": "2026-09-29T18:12:44Z"
    },
    {
      "id": "doc_5RJ2N7VKTB41",
      "kind": "report_data",
      "filename": "report_2026-1043.zip",
      "content_type": "application/zip",
      "size_bytes": 1044210,
      "created_at": "2026-09-29T18:12:44Z"
    },
    {
      "id": "doc_8QL4P9WMYC72",
      "kind": "invoice",
      "filename": "invoice_2026-1043.pdf",
      "content_type": "application/pdf",
      "size_bytes": 88120,
      "created_at": "2026-09-29T18:12:45Z"
    }
  ],
  "page": 1,
  "per_page": 25,
  "total": 3,
  "total_pages": 1
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
POST/orders/{order_id}/documents

Upload a supporting document

Uploads a document to an open order: a purchase and sale contract, an engagement letter, comparable sales for a reconsideration, or anything else the appraiser needs.

A document you upload is visible to the appraisal management company and to the assigned appraiser. Send purpose to say what it is: engagement_letter, sales_contract, prior_report or other.

Send multipart/form-data with a file part and a kind part. The limit is 25 MB per file; a larger file is refused with 413. Accepted media types are PDF, JPEG, PNG, TIFF, ZIP, plain text, XML, and the common office document types; anything else is refused with 415. kind must be supporting on an upload: a report, a report data file, an invoice or a certificate is produced by the appraisal management company, never uploaded by a lender.

Request bodyrequired

Content type: multipart/form-data

FieldTypeDescription
filerequiredstring (binary)The file. Up to 25 MB.
kindrequiredstringOnly supporting may be uploaded by a lender.
purposestring enumWhat a document you upload is for. Optional; other is assumed when you leave it out.One of: engagement_letter, sales_contract, prior_report, other
descriptionstringWhat the file is, for the appraiser.

Example request

{
  "file": "(the bytes of purchase_and_sale.pdf)",
  "kind": "supporting",
  "purpose": "sales_contract",
  "description": "Purchase and sale contract"
}

Responses

201
The document was stored on the order.
{
  "id": "doc_2KM7Q0VZTC93",
  "kind": "supporting",
  "filename": "purchase_and_sale.pdf",
  "content_type": "application/pdf",
  "size_bytes": 412998,
  "created_at": "2026-09-17T14:40:11Z"
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
409
The request is well formed but conflicts with the order's current state: an action the status does not allow, an amendment to a closed order, or a reused idempotency key.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "A closed order cannot be amended.",
  "current_status": "cancelled",
  "details": [
    {
      "field": "status",
      "code": "current_status",
      "value": "cancelled",
      "message": "The order has been cancelled."
    }
  ],
  "correlation_id": "req_01J9Z44W6Y9B2D5F8H1K4M7P"
}
413
The upload is larger than 25 MB.
Example error body
{
  "code": "payload_too_large",
  "message": "The file is larger than the 25 MB limit.",
  "correlation_id": "req_01J9Z45Y8B1D4F7H0K3M6P9R"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
GET/documents/{document_id}

Get a document and a link to download it

Returns the document's details and a signed download link that is valid for five minutes and may be used more than once inside that window. Follow the link with a plain GET and no credential of ours: the signature in the link is the authorization. The expires value in the link is expires_at in Unix seconds. Fetch a fresh link when one expires rather than storing links.

A document you are not entitled to see returns 404, not 403, so that ids cannot be probed.

Responses

200
The document, with a signed link.
{
  "id": "doc_5RJ2N7VKTB41",
  "order_id": "ord_9TBK4C2QFA7M",
  "kind": "report_data",
  "filename": "report_2026-1043.zip",
  "content_type": "application/zip",
  "size_bytes": 1044210,
  "created_at": "2026-09-29T18:12:44Z",
  "download": {
    "url": "https://api.appraisalhost.com/v1/download/doc_5RJ2N7VKTB41?expires=1790705864&signature=4f1c8e2b9a7d5c3f6e0b8a2d4c6f1e9b",
    "expires_at": "2026-09-29T18:17:44Z"
  }
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such resource, or one your credential is not entitled to see. We return 404 rather than 403 for another account's resource so that ids cannot be probed.
Example error body
{
  "code": "not_found",
  "message": "No order with that id.",
  "correlation_id": "req_01J9Z43T4W7Y0B3D6F9H2K5M"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Events

Every event we raised for your client, with its webhook delivery state. Use this feed to catch up after an outage and to reconcile.
GET/events

Read your event feed

Returns the events we raised for your client, ordered by created_at ascending, which is also event id order, each with its webhook delivery state. This is the catch-up feed: if your endpoint was down, read forward from the last event id you processed and you will miss nothing.

This endpoint uses a cursor rather than page numbers. Pass the last id you processed as after, and keep reading while next_cursor is not null. Events are retained for 30 days.

Parameters

NameInTypeDescription
afterquerystringReturn events after this event id. Omit to start at the oldest retained event.
typequerystringOne or more event types, comma separated.
order_idquerystringReturn only events for this order.
delivery_statusquerystring enumReturn only events in this delivery state.
per_pagequeryintegerHow many items to return per page, from 1 to 100.

Responses

200
A page of events.
{
  "data": [
    {
      "id": "evt_01M2T9W27R459H4DHVZGW4WNSS",
      "type": "order.status_changed",
      "created_at": "2026-09-18T13:04:11Z",
      "order_id": "ord_9TBK4C2QFA7M",
      "data": {
        "order_id": "ord_9TBK4C2QFA7M",
        "order_number": "2026-1043",
        "status": {
          "code": "appraiser_assigned",
          "label": "Appraiser Assigned",
          "changed_at": "2026-09-18T13:04:11Z"
        },
        "previous_status": {
          "code": "new",
          "label": "New Order"
        }
      },
      "delivery": {
        "status": "delivered",
        "attempts": 1,
        "last_attempt_at": "2026-09-18T13:04:13Z",
        "next_attempt_at": null,
        "last_response_status": 200
      }
    },
    {
      "id": "evt_01M3Q5WZA8V0AB3B4S4B8E3XC5",
      "type": "order.completed",
      "created_at": "2026-09-29T18:12:45Z",
      "order_id": "ord_9TBK4C2QFA7M",
      "data": {
        "order_id": "ord_9TBK4C2QFA7M",
        "order_number": "2026-1043",
        "report_format": "uad_3_6",
        "documents": [
          {
            "id": "doc_3XH8M1PLQW60",
            "kind": "report_pdf",
            "filename": "report_2026-1043.pdf",
            "content_type": "application/pdf",
            "size_bytes": 2841773,
            "created_at": "2026-09-29T18:12:44Z"
          },
          {
            "id": "doc_5RJ2N7VKTB41",
            "kind": "report_data",
            "filename": "report_2026-1043.zip",
            "content_type": "application/zip",
            "size_bytes": 1044210,
            "created_at": "2026-09-29T18:12:44Z"
          },
          {
            "id": "doc_8QL4P9WMYC72",
            "kind": "invoice",
            "filename": "invoice_2026-1043.pdf",
            "content_type": "application/pdf",
            "size_bytes": 88120,
            "created_at": "2026-09-29T18:12:45Z"
          }
        ],
        "completed_at": "2026-09-29T18:12:44Z"
      },
      "delivery": {
        "status": "failed",
        "attempts": 3,
        "last_attempt_at": "2026-09-29T18:48:02Z",
        "next_attempt_at": "2026-09-29T20:48:02Z",
        "last_response_status": 502
      }
    }
  ],
  "next_cursor": "evt_01M3Q5WZA8V0AB3B4S4B8E3XC5"
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Webhook Configuration

Read and update the endpoint we deliver your events to, and send yourself a test delivery.
POST/webhook/test

Send yourself a signed test event

Delivers one signed specimen event of the type you name to your configured endpoint, and returns what your endpoint answered. Use it to prove your signature check, your timestamp tolerance and your ten second acknowledgement before you place an order.

The delivery is signed with your current secret and carries the same headers as a real one. Its envelope carries "test": true, and it is not written to your feed, so GET /events is unaffected. Its payload carries a synthetic order_id, always prefixed ord_test_, which no real order in any environment ever carries, so a specimen can never be mistaken for one of your orders. It works in both environments, on the same terms: a handler that sees test true verifies the signature, answers 2xx, and stops, without storing the event or looking the order up. A client with no webhook configured is refused with 404 and code webhook_not_configured.

Request bodyrequired

Content type: application/json

FieldTypeDescription
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed

Example request

{
  "type": "order.status_changed"
}

Responses

200
The delivery was attempted. Read delivered for the outcome.
{
  "event_id": "evt_01M2TM1N60M4HGM9QGTHVCDMA2",
  "type": "order.status_changed",
  "url": "https://los.example.com/hooks/appraisal-host",
  "delivered": true,
  "response_status": 200,
  "response_time_ms": 142,
  "error": null,
  "attempted_at": "2026-09-18T16:02:04Z"
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No webhook has been configured for this client yet.
Example error body
{
  "code": "webhook_not_configured",
  "message": "No webhook endpoint has been configured for this client.",
  "correlation_id": "req_01J9Z3K4R7T0W3Y6B9D2F5H8"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
GET/webhook

Read your webhook configuration

Returns the endpoint we deliver your events to, which event types you are subscribed to, and when the signing secret was last rotated. The secret itself is never returned.

Responses

200
Your webhook configuration.
{
  "url": "https://los.example.com/hooks/appraisal-host",
  "enabled": true,
  "events": [
    "*"
  ],
  "secret_set": true,
  "secret_rotated_at": "2026-09-15T09:00:00Z",
  "updated_at": "2026-09-15T09:00:00Z"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No webhook has been configured for this client yet.
Example error body
{
  "code": "webhook_not_configured",
  "message": "No webhook endpoint has been configured for this client.",
  "correlation_id": "req_01J9Z3K4R7T0W3Y6B9D2F5H8"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
PUT/webhook

Set or update your webhook configuration

Sets the endpoint we deliver your events to. The URL must be HTTPS and must answer a POST with a 2xx within 10 seconds.

This call replaces the fields you send and leaves the others as they are. Omitting events keeps your current subscription; omitting secret keeps your current secret, which this call never clears. Send "enabled": false to stop delivery without losing your configuration.

Send secret to set or rotate the signing secret. Use at least 32 characters of random text. We store it in a form we can sign with and never display it again, so keep your own copy. One secret is in force at a time, and every attempt is signed with the secret in force when that attempt is made, so a retry sent after a rotation carries the new secret. Change both sides together, or accept either signature for a short window.

Send events to subscribe to a subset of event types, or ["*"] for all of them. Unsubscribed events are still raised and still readable at GET /events; we simply do not deliver them.

The appraisal management company can also set this endpoint for you from its own screens. The last write wins, whichever side made it.

Request bodyrequired

Content type: application/json

FieldTypeDescription
urlrequiredstring (uri)An HTTPS URL that answers a POST with a 2xx within 10 seconds.
enabledbooleanSend false to stop delivery without losing your configuration.
eventsarray of stringEvent types to subscribe to, or ["*"] for all of them. Leave it out to keep your current subscription.
secretstringSet or rotate the signing secret. At least 32 characters of random text. Never returned, and never cleared by this call: leave it out to keep the secret you have.

Example request

{
  "url": "https://los.example.com/hooks/appraisal-host",
  "enabled": true,
  "events": [
    "order.status_changed",
    "order.completed",
    "order.document_added"
  ],
  "secret": "example_webhook_secret_replace_this_with_32_random_characters"
}

Responses

200
The configuration was saved.
{
  "url": "https://los.example.com/hooks/appraisal-host",
  "enabled": true,
  "events": [
    "order.status_changed",
    "order.completed",
    "order.document_added"
  ],
  "secret_set": true,
  "secret_rotated_at": "2026-09-17T14:45:00Z",
  "updated_at": "2026-09-17T14:45:00Z"
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Sandbox

Sandbox only. Move a test order through the lifecycle so that your own test suite can exercise every status and every event without anyone else being involved.
POST/sandbox/orders/{order_id}/advance

Move a sandbox order to another status

Moves one of your sandbox orders to the status you name and raises everything a real move raises: the same events, the same payloads, the same signed deliveries to your endpoint.

Three rules govern it.

  • It exists in the sandbox environment only. The same path in production returns 404.
  • The transition table below is the whole rule for to_status. You may skip statuses, because a real order often does. You may not move an order backwards, you may not name the status the order is already at, and you may not reach pending_review, revision_requested, reconsideration_requested, on_hold, off_hold, cancelled or reactivated this way: those are produced by POST /orders, by POST /orders/{order_id}/revision-requests, and by hold, resume and cancel, which work in the sandbox exactly as they do in production. A move the table does not list is refused with 409 and code action_not_allowed_in_status, with the order's current status in current_status and the status you asked for in details[0].value.
  • It fires the same notifications production fires.
Current statusto_status you may name
pending_reviewnew
newappraiser_assigned, appraiser_accepted, borrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_rejected_for_correction, report_complete
appraiser_assignedappraiser_accepted, borrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_rejected_for_correction, report_complete
appraiser_acceptedborrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_rejected_for_correction, report_complete
borrower_contactedleft_message_for_borrower, appointment_scheduled, awaiting_review, report_rejected_for_correction, report_complete
left_message_for_borrowerborrower_contacted, appointment_scheduled, awaiting_review, report_rejected_for_correction, report_complete
appointment_scheduledawaiting_review, report_rejected_for_correction, report_complete
awaiting_reviewreport_rejected_for_correction, report_complete
report_rejected_for_correctionawaiting_review, report_complete
report_completeNothing. Open a correction or a reconsideration first, which moves the order to revision_requested or reconsideration_requested.
revision_requestedrevised_report_complete
reconsideration_requestedrevised_report_complete
revised_report_completeNothing. Open another correction first.
on_hold, cancelledNothing. Resume a held order first; a cancelled order is not advanced.

An order at off_hold or reactivated may be advanced to whatever the table allows for the status it held before the hold or the cancellation, which the hold and cancel responses give you in previous_status.

Drive your test suite from this call: place an order, advance it through assignment, appointment, review and delivery, and assert on what your listener received.

Request bodyrequired

Content type: application/json

FieldTypeDescription
to_statusrequiredstring enumThe status to move the order to. These are the statuses this call can set. pending_review is set by order creation, revision_requested and reconsideration_requested by POST /orders/{order_id}/revision-requests, and on_hold, off_hold, cancelled and reactivated by hold, resume and cancel, so none of them can be named here. Which of these is legal from the order's current status is in the transition table on the advance operation.One of: new, appraiser_assigned, appraiser_accepted, borrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_rejected_for_correction, report_complete, revised_report_complete
notestring or nullOptional text to carry on the status, as a company would enter it.

Example request

{
  "to_status": "appraiser_assigned"
}

Responses

200
The order after the move.
{
  "id": "ord_9TBK4C2QFA7M",
  "order_number": "2026-1043",
  "lender_reference": "LN-2026-88421",
  "status": {
    "code": "pending_review",
    "label": "Appraiser Assigned",
    "changed_at": "2026-09-17T14:30:00Z"
  },
  "order_type": {
    "code": "SFR-1004-36",
    "name": "Single Family Residential, current report standard",
    "report_format": "uad_2_6",
    "appraiser_certification": "none"
  },
  "loan": {
    "purpose": "construction_only",
    "purpose_other": "string",
    "number": "88421",
    "client": "string",
    "investor": "string",
    "agency_case_number": "string",
    "fha_case_number": "string",
    "purchase_price": "415000.00",
    "currency": "USD",
    "loan_type": {
      "code": "conventional",
      "name": "Conventional"
    },
    "add_ons": [
      {
        "code": "conventional",
        "name": "Conventional"
      }
    ]
  },
  "property": {
    "address": {
      "street": "100 Example Avenue",
      "unit": "Unit 2",
      "city": "Springfield",
      "state": "IL",
      "postal_code": "62701",
      "county": "Sangamon"
    },
    "type": "church",
    "occupancy": "investment_property",
    "has_adu": true
  },
  "borrowers": [
    {
      "first_name": "Sample",
      "last_name": "Borrower",
      "address": {},
      "receives_report": false,
      "receives_status_updates": false,
      "role": "borrower",
      "contacts": [
        {}
      ]
    }
  ],
  "parties": {
    "real_estate_agent": {
      "first_name": "string",
      "last_name": "string",
      "company": "string",
      "contacts": [
        {}
      ]
    },
    "additional_contacts": [
      {
        "purpose": "report",
        "name": "string",
        "email": "processing@example.com"
      }
    ]
  },
  "notes": [
    {
      "type": "order",
      "text": "string"
    }
  ],
  "flags": {
    "rush": false,
    "complex": false,
    "rural": false,
    "priority": false,
    "certified_appraiser_required": false
  },
  "appraiser_instructions": "string",
  "appraiser": {
    "name": "J. Marsh"
  },
  "dates": {
    "created_at": "2026-09-17T14:30:00Z",
    "updated_at": "2026-09-17T14:30:00Z",
    "due_date": "2026-09-30",
    "appointment_at": "2026-09-17T14:30:00Z",
    "completed_at": "2026-09-17T14:30:00Z"
  },
  "fees": {
    "appraisal_fee": "525.00",
    "currency": "USD"
  },
  "documents": [
    {
      "id": "doc_5RJ2N7VKTB41",
      "kind": "report_pdf",
      "filename": "report_2026-1043.zip",
      "content_type": "application/zip",
      "size_bytes": 1044210,
      "description": "string",
      "created_at": "2026-09-17T14:30:00Z"
    }
  ]
}
400
The request could not be read: malformed JSON, a missing required field, or a value of the wrong type. details names each field at fault.
Example error body
{
  "code": "validation_failed",
  "message": "The request could not be processed. See details.",
  "details": [
    {
      "field": "property.postal_code",
      "code": "required",
      "value": null,
      "message": "A postal code is required."
    },
    {
      "field": "loan.purpose",
      "code": "invalid_value",
      "value": "cash_out",
      "message": "Must be one of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance."
    }
  ],
  "correlation_id": "req_01J9Z40M8P1R4T7W0Y3B6D9F"
}
401
No token was sent, the token is not valid, or the token has expired. Ask for a new token and retry once.
Example error body
{
  "code": "token_expired",
  "message": "The access token has expired.",
  "correlation_id": "req_01J9Z41P0R3T6W9Y2B5D8F1H"
}
403
The credential is valid but is not allowed to do this: the action is switched off for this client, or the resource belongs to another lender account.
Example error body
{
  "code": "action_not_permitted_for_client",
  "message": "This client is not permitted to cancel orders.",
  "correlation_id": "req_01J9Z42R2T5W8Y1B4D7F0H3K"
}
404
No such order, or this path does not exist in this environment. It exists in the sandbox only.
Example error body
{
  "code": "not_found",
  "message": "No order with that id in this environment.",
  "correlation_id": "req_01J9Z3K4R7T0W3Y6B9D2F5H8"
}
409
The order's current status does not allow that move.
Example error body
{
  "code": "action_not_allowed_in_status",
  "message": "An order cannot be moved backwards.",
  "current_status": "report_complete",
  "details": [
    {
      "field": "to_status",
      "code": "not_applicable",
      "value": "appraiser_assigned",
      "message": "The order is already at report_complete."
    }
  ],
  "correlation_id": "req_01J9Z3K4R7T0W3Y6B9D2F5H8"
}
415
The Content-Type is not supported. JSON endpoints require application/json; the upload endpoint requires multipart/form-data with a file of an accepted type.
Example error body
{
  "code": "unsupported_media_type",
  "message": "Send application/json.",
  "correlation_id": "req_01J9Z46B0D3F6H9K2M5P8R1T"
}
422
The request is well formed and the fields are of the right type, but the values cannot be used: an order type this lender may not order, a loan type that does not apply to the product, a due date in the past, an acknowledgement missing from a reconsideration.
Example error body
{
  "code": "semantic_validation_failed",
  "message": "The loan type does not apply to this order type.",
  "details": [
    {
      "field": "loan_type_code",
      "code": "not_applicable",
      "value": "va",
      "message": "That loan type is not available on order type SFR-1004-FHA. Read GET /order-types for the loan types the product accepts."
    }
  ],
  "correlation_id": "req_01J9Z47D2F5H8K1M4P7R0T3W"
}
429
You have made more requests than your limit allows. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "rate_limited",
  "message": "Too many requests. Retry after 30 seconds.",
  "correlation_id": "req_01J9Z48F4H7K0M3P6R9T2W5Y"
}
500
Something failed on our side. The request may or may not have been applied: retry a read, and retry a create with the same Idempotency-Key. For a write that takes no key, such as a message, an upload or a revision request, read the order first rather than sending it again. Quote the correlation_id to our integrations team.
Example error body
{
  "code": "internal_error",
  "message": "The request could not be completed. Quote the correlation id if it continues.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}
503
The API is not serving requests for a moment, for example during planned maintenance. Nothing you sent was applied. Wait for the number of seconds in Retry-After and retry.
Example error body
{
  "code": "service_unavailable",
  "message": "The API is briefly unavailable. Retry after the interval in Retry-After.",
  "correlation_id": "req_01J9Z49H6K9M2P5R8T1W4Y7B"
}

Notifications

Each notification is an HTTPS POST to the address you configure. Verify the signature before acting on the payload.

EVENTorder.created

An order was created

Raised when an order is created for your lender account, including orders placed in the portal by the lender's own staff rather than through the API.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M2QWG9M8BSNHMTEF5XX0GB38",
  "type": "order.created",
  "created_at": "2026-09-17T14:32:05Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "lender_reference": "LN-2026-88421",
    "order_type": {
      "code": "SFR-1004-36",
      "name": "Single Family Residential, current report standard",
      "report_format": "uad_3_6",
      "appraiser_certification": "none"
    },
    "status": {
      "code": "new",
      "label": "New Order",
      "changed_at": "2026-09-17T14:32:05Z"
    },
    "due_date": "2026-10-02",
    "created_at": "2026-09-17T14:32:05Z"
  }
}
EVENTorder.status_changed

An order's status changed

Raised on every change to the status the lender sees. An order is always reported with the status the lender sees in the portal, in the same words.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M2T9W27R459H4DHVZGW4WNSS",
  "type": "order.status_changed",
  "created_at": "2026-09-18T13:04:11Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "status": {
      "code": "appraiser_assigned",
      "label": "Appraiser Assigned",
      "changed_at": "2026-09-18T13:04:11Z"
    },
    "previous_status": {
      "code": "new",
      "label": "New Order"
    },
    "note": "Assigned to a certified appraiser covering Sangamon county."
  }
}
EVENTorder.assigned

An appraiser was assigned

Raised when the appraisal management company assigns an appraiser. The event always fires. appraiser carries the appraiser's display name where the company shares the assigned appraiser with its lenders, and is null where it does not.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M2T9W27RXJWVPHSK03CJAJQH",
  "type": "order.assigned",
  "created_at": "2026-09-18T13:04:11Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "appraiser": {
      "name": "J. Marsh"
    },
    "assigned_at": "2026-09-18T13:04:11Z"
  }
}
EVENTorder.on_hold

An order was placed on hold

Raised when an order is put on hold, whoever put it there.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M2WN9220WJX8W2ZDA9CMHHKM",
  "type": "order.on_hold",
  "created_at": "2026-09-19T11:02:00Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "status": {
      "code": "on_hold",
      "label": "On Hold",
      "changed_at": "2026-09-19T11:02:00Z"
    },
    "reason": "Borrower is renegotiating the purchase price."
  }
}
EVENTorder.resumed

An order resumed from hold

Raised when an order comes off hold and work restarts.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M344BJF0DA2RXN7VKXTHJWEG",
  "type": "order.resumed",
  "created_at": "2026-09-22T08:40:12Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "status": {
      "code": "off_hold",
      "label": "Off Hold",
      "changed_at": "2026-09-22T08:40:12Z"
    },
    "reason": "Purchase price agreed, please proceed."
  }
}
EVENTorder.cancelled

An order was cancelled

Raised when an order is cancelled, whoever cancelled it.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M2ZT0NARH2NGSGKRP6ZFPYN7",
  "type": "order.cancelled",
  "created_at": "2026-09-20T16:22:31Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "status": {
      "code": "cancelled",
      "label": "Order Cancelled",
      "changed_at": "2026-09-20T16:22:31Z"
    },
    "reason": "Loan withdrawn by the borrower."
  }
}
EVENTorder.completed

A report was delivered

Raised when the report is delivered, and again when a revised report is delivered. documents lists every file that came with the delivery, each as a separate document. Fetch each one with GET /documents/{document_id} to obtain a signed link.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M3Q5WZA8V0AB3B4S4B8E3XC5",
  "type": "order.completed",
  "created_at": "2026-09-29T18:12:45Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "status": {
      "code": "report_complete",
      "label": "Report Complete",
      "changed_at": "2026-09-29T18:12:44Z"
    },
    "report_format": "uad_3_6",
    "revision": false,
    "completed_at": "2026-09-29T18:12:44Z",
    "documents": [
      {
        "id": "doc_3XH8M1PLQW60",
        "kind": "report_pdf",
        "filename": "report_2026-1043.pdf",
        "content_type": "application/pdf",
        "size_bytes": 2841773,
        "created_at": "2026-09-29T18:12:44Z"
      },
      {
        "id": "doc_5RJ2N7VKTB41",
        "kind": "report_data",
        "filename": "report_2026-1043.zip",
        "content_type": "application/zip",
        "size_bytes": 1044210,
        "created_at": "2026-09-29T18:12:44Z"
      },
      {
        "id": "doc_8QL4P9WMYC72",
        "kind": "invoice",
        "filename": "invoice_2026-1043.pdf",
        "content_type": "application/pdf",
        "size_bytes": 88120,
        "created_at": "2026-09-29T18:12:45Z"
      }
    ]
  }
}
EVENTorder.document_added

A document was added to an order

Raised when a document the lender may see is added to an order, including the files that arrive with a delivery and anything the company adds later.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M3Q5WZA8WNXQQRS6N3X84JWZ",
  "type": "order.document_added",
  "created_at": "2026-09-29T18:12:45Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "document": {
      "id": "doc_8QL4P9WMYC72",
      "kind": "invoice",
      "filename": "invoice_2026-1043.pdf",
      "content_type": "application/pdf",
      "size_bytes": 88120,
      "created_at": "2026-09-29T18:12:45Z"
    }
  }
}
EVENTorder.message_posted

A message was posted on an order

Raised when a message the lender is party to is posted by the appraisal management company or the appraiser. Your own messages do not raise this event.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M2TM1N60M4HGM9QGTHVCDMA2",
  "type": "order.message_posted",
  "created_at": "2026-09-18T16:02:00Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "message": {
      "id": "msg_8TH2U5AYVF18",
      "order_id": "ord_9TBK4C2QFA7M",
      "recipient": "lender",
      "subject": "Access arrangements",
      "body": "Understood. The appraiser will call the agent to confirm.",
      "author": {
        "type": "manager",
        "name": "Order Desk"
      },
      "attachments": [],
      "created_at": "2026-09-18T16:02:00Z"
    }
  }
}
EVENTorder.revision_requested

A revision request was opened

Raised when a correction or a reconsideration of value is opened on the order, whether through the API or in the portal.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M3RWBA6G2CGMPB7GYCEAG70Y",
  "type": "order.revision_requested",
  "created_at": "2026-09-30T10:04:18Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "revision_request": {
      "id": "rr_6PD3K8YWQN25",
      "order_id": "ord_9TBK4C2QFA7M",
      "kind": "reconsideration_of_value",
      "status": "submitted",
      "reason": "Three closed sales within 0.4 miles support a higher value.",
      "acknowledgements": {
        "prior_appraisal_provided": false,
        "comparable_sales_provided": true
      },
      "documents": [],
      "responses": [],
      "created_at": "2026-09-30T10:04:18Z",
      "updated_at": "2026-09-30T10:04:18Z"
    }
  }
}
EVENTorder.revision_responded

A revision request was answered

Raised when the appraisal management company accepts, declines or comments on a revision request. A revised report that follows arrives as order.completed with revision set to true.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M3SFKTQ0PPQ3NCREDTYS1BKE",
  "type": "order.revision_responded",
  "created_at": "2026-09-30T15:41:00Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "revision_request_id": "rr_6PD3K8YWQN25",
    "status": "accepted",
    "response": {
      "id": "msg_4NF9R2XWTD86",
      "created_at": "2026-09-30T15:41:00Z",
      "author": {
        "type": "manager",
        "name": "Order Desk"
      },
      "message": "Sent to the appraiser for review. Revised report expected within two business days."
    }
  }
}
EVENTorder.due_date_changed

An order's due date changed

Raised when the due date on the order changes, including when the appraisal management company accepts or adjusts a date you requested.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M2WFE9G0VF1S24AE8RTAH2ZC",
  "type": "order.due_date_changed",
  "created_at": "2026-09-19T09:20:00Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "due_date": "2026-10-06",
    "previous_due_date": "2026-10-02",
    "requested_by": "lender"
  }
}
EVENTorder.fee_changed

An order's fee changed

Raised when the fee the lender is charged changes. The fee is read only through the API: fee negotiation happens between the appraisal management company and the lender, not over this interface.

Parameters

NameInTypeDescription
X-AH-SignaturerequiredheaderstringThe signature over the delivery, as t=<unix seconds>,v1=<hex>. v1 is a hex encoded HMAC-SHA256 of the string <t>.<raw request body> keyed with your webhook secret. t is when we signed this attempt, not when the event was raised: a retry hours later carries a fresh t and the original created_at. Compare v1 with a constant time comparison, and reject a delivery whose t is more than five minutes from your own clock.
X-AH-Event-IdrequiredheaderstringThe event id, the same value as id in the body. Use it to make your handler idempotent.
X-AH-Event-TyperequiredheaderstringThe event type, the same value as type in the body. Useful for routing before you parse.

Payload

{
  "id": "evt_01M31Z3MA00XVKABD7905AR0R1",
  "type": "order.fee_changed",
  "created_at": "2026-09-21T12:30:00Z",
  "api_version": "1.0.0",
  "data": {
    "order_id": "ord_9TBK4C2QFA7M",
    "order_number": "2026-1043",
    "appraisal_fee": "575.00",
    "previous_appraisal_fee": "525.00",
    "currency": "USD",
    "reason": "Complex property, additional scope agreed with the lender."
  }
}

Objects

Every object the API sends or accepts, with its fields. Open one to read it.

Ping
The liveness response.
FieldTypeDescription
statusrequiredstring
timerequiredstring (date-time)Our clock in UTC, useful when you verify signature timestamps.
TokenRequest
A client credentials token request.
FieldTypeDescription
grant_typerequiredstring
client_idrequiredstringThe client id we issued. Always starts with cli_.
client_secretrequiredstringThe client secret we issued. Shown once, at creation. Store it in a secret manager.
scopestringOptional. The only scope in version 1 is lender, which is also the default.
TokenResponse
A bearer token.
FieldTypeDescription
access_tokenrequiredstringThe opaque token. Send it as Authorization: Bearer <access_token>.
token_typerequiredstring
expires_inrequiredintegerSeconds until the token expires, counted from this response.
scoperequiredstring
Error
The one error shape. code is stable and safe to branch on. message is plain text for a human and may be reworded. details names the fields at fault when the failure is a validation failure.
FieldTypeDescription
coderequiredstringA stable machine readable code.
messagerequiredstringA plain description of what went wrong.
current_statusone ofThe order's current status code. Present on every 409 that refuses an action because of the status the order has reached, so that you can branch without walking details. Absent on every other error.
detailsarray of ErrorDetailOne entry per field at fault, when applicable.
correlation_idrequiredstringThe identifier for this request in our logs. Quote it when you contact us.
ErrorDetail
One field level problem.
FieldTypeDescription
fieldrequiredstringA dotted path to the field, for example property.postal_code or borrowers.0.last_name.
coderequiredstringA stable reason: required, invalid_value, too_long, not_applicable, not_found, current_status.
valuestring or nullThe machine readable value at fault, when there is one: the value you sent, or the order's current status code on a 409. Safe to branch on. message never is.
messagerequiredstringA plain explanation for a person. Never match on it.
OAuthError
The error body at POST /oauth/token only, in the shape RFC 6749 defines. Every other endpoint uses Error.
FieldTypeDescription
errorrequiredstring enumOne of: invalid_request, invalid_client, invalid_grant, unauthorized_client, unsupported_grant_type, invalid_scope
error_descriptionstring or nullA plain explanation for a person. Never match on it.
correlation_idstring or nullThe identifier for this request in our logs.
AccountParty
A named party on the account.
FieldTypeDescription
idrequiredstring
namerequiredstring
AccountRateLimit
The published limit for this client.
FieldTypeDescription
requests_per_minuterequiredinteger
Account
What a credential resolves to. Read it at start-up and assert on it.
FieldTypeDescription
client_idrequiredstringYour client id. Safe to log.
environmentrequiredstring enumThe environment this credential works in.One of: sandbox, production
lenderrequiredobjectThe lender account orders placed with this credential belong to.
companyrequiredobjectThe appraisal management company that holds the lender account.
scopesrequiredarray of stringThe scopes the credential carries. Version 1 issues lender.
rate_limitrequiredAccountRateLimitThe published limit for this client.
SandboxAdvance
Sandbox only. The status to move a test order to.
FieldTypeDescription
to_statusrequiredstring enumThe status to move the order to. These are the statuses this call can set. pending_review is set by order creation, revision_requested and reconsideration_requested by POST /orders/{order_id}/revision-requests, and on_hold, off_hold, cancelled and reactivated by hold, resume and cancel, so none of them can be named here. Which of these is legal from the order's current status is in the transition table on the advance operation.One of: new, appraiser_assigned, appraiser_accepted, borrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_rejected_for_correction, report_complete, revised_report_complete
notestring or nullOptional text to carry on the status, as a company would enter it.
WebhookTestRequest
Which specimen event to send yourself.
FieldTypeDescription
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
WebhookTestResult
What your endpoint did with the test delivery. The event it delivered carries test true and a synthetic order_id, always prefixed ord_test_, which no real order in any environment ever carries. It is not written to your feed, and no order changed.
FieldTypeDescription
event_idrequiredstringThe id carried by the specimen event. It is not stored in your feed.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
urlrequiredstring (uri)The endpoint we delivered to.
deliveredrequiredbooleanTrue when your endpoint answered with a 2xx inside ten seconds.
response_statusinteger or nullThe status your endpoint returned, when it returned one.
response_time_msinteger or null
errorstring or nullWhat went wrong, when the delivery failed.
attempted_atrequiredstring (date-time)
Pagination
The page envelope shared by every list endpoint except the event feed.
FieldTypeDescription
pagerequiredinteger
per_pagerequiredinteger
totalrequiredintegerHow many items match in total.
total_pagesrequiredinteger
ReportFormat
The report standard a product is delivered in.
  • uad_2_6: the report arrives as a PDF, plus report_data as the MISMO 2.6 GSE appraisal XML, with the report PDF embedded as that standard defines.
  • uad_3_6: the report arrives as a PDF, plus report_data as the UAD 3.6 delivery package, a ZIP produced by the appraiser's forms software to the GSE UAD 3.6 specification. The members of that package are defined by that specification. The package is delivered exactly as the forms software produced it, so whether a copy of the report PDF sits inside it is that software's doing; report_pdf is always delivered as its own file as well, and that is the copy to read.
In both cases the invoice, the certificates and any other delivery document are separate files. The package replaces the report data file only; it never contains the invoice. Sample files for both formats are available from our integrations team.

One of: uad_2_6, uad_3_6

OrderStatusCode
The statuses this interface reports. An order is always reported with the status the lender sees in the portal, in the same words.
  • pending_review: received, and with the appraisal management company for a look before it is placed. Nothing is wrong.
  • new: received, not yet assigned.
  • appraiser_assigned: an appraiser has the order.
  • appraiser_accepted: the appraiser accepted the assignment.
  • borrower_contacted: the appraiser has reached the contact.
  • left_message_for_borrower: the appraiser left a message for the borrower or the broker.
  • appointment_scheduled: an inspection appointment is set.
  • awaiting_review: the report has been submitted and is in review before delivery.
  • report_complete: the report has been delivered. Documents are available.
  • report_rejected_for_correction: the report was sent back for correction before delivery.
  • revision_requested: a correction has been requested on a delivered report.
  • reconsideration_requested: a reconsideration of value has been requested.
  • revised_report_complete: a revised report has been delivered.
  • on_hold: work is paused.
  • off_hold: work has resumed after a hold.
  • cancelled: the order was cancelled.
  • reactivated: a cancelled order was put back into production.
off_hold and reactivated are transitional: an order at either moves on to its working status shortly afterwards, so read the order again rather than treating one as a resting state. Not every company uses every status, so treat this as the complete set of what you may receive and never as a sequence you must see. A few labels are ours rather than the company's, because the status they stand for is internal to the company. Branch on code, display label, and store a code you do not know rather than failing on it.

One of: pending_review, new, appraiser_assigned, appraiser_accepted, borrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_complete, report_rejected_for_correction, revision_requested, reconsideration_requested, revised_report_complete, on_hold, off_hold, cancelled, reactivated

OrderStatus
A status, as a stable code with display text.
FieldTypeDescription
coderequiredstring enumThe statuses this interface reports. An order is always reported with the status the lender sees in the portal, in the same words.
  • pending_review: received, and with the appraisal management company for a look before it is placed. Nothing is wrong.
  • new: received, not yet assigned.
  • appraiser_assigned: an appraiser has the order.
  • appraiser_accepted: the appraiser accepted the assignment.
  • borrower_contacted: the appraiser has reached the contact.
  • left_message_for_borrower: the appraiser left a message for the borrower or the broker.
  • appointment_scheduled: an inspection appointment is set.
  • awaiting_review: the report has been submitted and is in review before delivery.
  • report_complete: the report has been delivered. Documents are available.
  • report_rejected_for_correction: the report was sent back for correction before delivery.
  • revision_requested: a correction has been requested on a delivered report.
  • reconsideration_requested: a reconsideration of value has been requested.
  • revised_report_complete: a revised report has been delivered.
  • on_hold: work is paused.
  • off_hold: work has resumed after a hold.
  • cancelled: the order was cancelled.
  • reactivated: a cancelled order was put back into production.
off_hold and reactivated are transitional: an order at either moves on to its working status shortly afterwards, so read the order again rather than treating one as a resting state. Not every company uses every status, so treat this as the complete set of what you may receive and never as a sequence you must see. A few labels are ours rather than the company's, because the status they stand for is internal to the company. Branch on code, display label, and store a code you do not know rather than failing on it.One of: pending_review, new, appraiser_assigned, appraiser_accepted, borrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_complete, report_rejected_for_correction, revision_requested, reconsideration_requested, revised_report_complete, on_hold, off_hold, cancelled, reactivated
labelrequiredstringThe wording the lender sees. An appraisal management company may reword its own labels, so branch on code and display label.
changed_atrequiredstring (date-time)
OrderStatusRef
A status without a timestamp, used for a previous status.
FieldTypeDescription
coderequiredstring enumThe statuses this interface reports. An order is always reported with the status the lender sees in the portal, in the same words.
  • pending_review: received, and with the appraisal management company for a look before it is placed. Nothing is wrong.
  • new: received, not yet assigned.
  • appraiser_assigned: an appraiser has the order.
  • appraiser_accepted: the appraiser accepted the assignment.
  • borrower_contacted: the appraiser has reached the contact.
  • left_message_for_borrower: the appraiser left a message for the borrower or the broker.
  • appointment_scheduled: an inspection appointment is set.
  • awaiting_review: the report has been submitted and is in review before delivery.
  • report_complete: the report has been delivered. Documents are available.
  • report_rejected_for_correction: the report was sent back for correction before delivery.
  • revision_requested: a correction has been requested on a delivered report.
  • reconsideration_requested: a reconsideration of value has been requested.
  • revised_report_complete: a revised report has been delivered.
  • on_hold: work is paused.
  • off_hold: work has resumed after a hold.
  • cancelled: the order was cancelled.
  • reactivated: a cancelled order was put back into production.
off_hold and reactivated are transitional: an order at either moves on to its working status shortly afterwards, so read the order again rather than treating one as a resting state. Not every company uses every status, so treat this as the complete set of what you may receive and never as a sequence you must see. A few labels are ours rather than the company's, because the status they stand for is internal to the company. Branch on code, display label, and store a code you do not know rather than failing on it.One of: pending_review, new, appraiser_assigned, appraiser_accepted, borrower_contacted, left_message_for_borrower, appointment_scheduled, awaiting_review, report_complete, report_rejected_for_correction, revision_requested, reconsideration_requested, revised_report_complete, on_hold, off_hold, cancelled, reactivated
labelrequiredstring
LoanPurpose
Why the loan is being made. Send other with loan.purpose_other when nothing else fits.

One of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance

PropertyType
What kind of property is being appraised.

One of: church, commercial_non_residential, condominium, condominium_over_four_stories, cooperative, farm, home_and_business_combined, manufactured_mobile_home, mixed_use_residential, multifamily_more_than_four_units, other, single_family, townhouse, two_to_four_unit_property, vacant_land

Occupancy
How the property is occupied.

One of: investment_property, primary_residence, second_home, vacant

ContactType

One of: phone, email

ContactRole

One of: home, cell, work, other

Contact
One way to reach a person.
FieldTypeDescription
typerequiredstring enumOne of: phone, email
rolerequiredobjectWhose number or address this is. On an email address use home, work or other.
valuerequiredstringThe phone number or the email address. Phone numbers are text: include the country code, as in +1-217-555-0142, and read back what you sent.
Address
A United States street address. Properties and territories of the United States only. postal_code is required. city, state and county are filled in from it when you leave them out, and the filled in values are returned on the order. Where a postal code covers more than one place name we store the postal service's preferred name. A postal code we cannot resolve is refused with 422.
FieldTypeDescription
streetrequiredstring
unitstring or null
citystring or null
statestring or nullThe two letter state or territory code.
postal_coderequiredstring
countystring or null
CatalogItem
A code and its display name from an appraisal management company's own catalog.
FieldTypeDescription
coderequiredstringStable for this company. Send this value, not the name.
namerequiredstringDisplay text. May be reworded.
AppraiserCertification
Which appraiser certification a product requires.
  • none: no special certification.
  • fha_required: only an FHA approved appraiser may take it, and loan.fha_case_number is required on the order.
  • fha_optional: an FHA approved appraiser may take it, and the case number is accepted but not required.
  • usda: a USDA product, and loan.fha_case_number is required on the order.

One of: none, fha_required, fha_optional, usda

OrderTypeRef
The product an order was placed against.
FieldTypeDescription
coderequiredstringThe product code. Codes belong to the appraisal management company and are opaque: treat one as a string and read it from GET /order-types. Some companies use numbers. A product appears only when the company has enabled it for API ordering and given it a code.
namerequiredstring
report_formatrequiredstring enumThe report standard a product is delivered in.
  • uad_2_6: the report arrives as a PDF, plus report_data as the MISMO 2.6 GSE appraisal XML, with the report PDF embedded as that standard defines.
  • uad_3_6: the report arrives as a PDF, plus report_data as the UAD 3.6 delivery package, a ZIP produced by the appraiser's forms software to the GSE UAD 3.6 specification. The members of that package are defined by that specification. The package is delivered exactly as the forms software produced it, so whether a copy of the report PDF sits inside it is that software's doing; report_pdf is always delivered as its own file as well, and that is the copy to read.
In both cases the invoice, the certificates and any other delivery document are separate files. The package replaces the report data file only; it never contains the invoice. Sample files for both formats are available from our integrations team.One of: uad_2_6, uad_3_6
appraiser_certificationrequiredstring enumWhich appraiser certification a product requires.
  • none: no special certification.
  • fha_required: only an FHA approved appraiser may take it, and loan.fha_case_number is required on the order.
  • fha_optional: an FHA approved appraiser may take it, and the case number is accepted but not required.
  • usda: a USDA product, and loan.fha_case_number is required on the order.
One of: none, fha_required, fha_optional, usda
OrderType
FieldTypeDescription
coderequiredstringThe product code. Codes belong to the appraisal management company and are opaque: treat one as a string and read it from GET /order-types. Some companies use numbers. A product appears only when the company has enabled it for API ordering and given it a code.
namerequiredstring
report_formatrequiredstring enumThe report standard a product is delivered in.
  • uad_2_6: the report arrives as a PDF, plus report_data as the MISMO 2.6 GSE appraisal XML, with the report PDF embedded as that standard defines.
  • uad_3_6: the report arrives as a PDF, plus report_data as the UAD 3.6 delivery package, a ZIP produced by the appraiser's forms software to the GSE UAD 3.6 specification. The members of that package are defined by that specification. The package is delivered exactly as the forms software produced it, so whether a copy of the report PDF sits inside it is that software's doing; report_pdf is always delivered as its own file as well, and that is the copy to read.
In both cases the invoice, the certificates and any other delivery document are separate files. The package replaces the report data file only; it never contains the invoice. Sample files for both formats are available from our integrations team.One of: uad_2_6, uad_3_6
appraiser_certificationrequiredstring enumWhich appraiser certification a product requires.
  • none: no special certification.
  • fha_required: only an FHA approved appraiser may take it, and loan.fha_case_number is required on the order.
  • fha_optional: an FHA approved appraiser may take it, and the case number is accepted but not required.
  • usda: a USDA product, and loan.fha_case_number is required on the order.
One of: none, fha_required, fha_optional, usda
descriptionstring or nullThe company's own description of the product, when it has set one.
activerequiredbooleanFalse when the company has withdrawn the product. A withdrawn product cannot be ordered.
loan_typesrequiredarray of CatalogItemThe loan type tier that may be attached to this product. Empty for a product that does not take one, which today means every product other than those on the current report standard. When the list is not empty, loan_type_code is required on create.
add_onsrequiredarray of CatalogItemThe add-ons that may be attached to this product. Add-ons are not particular to one report standard: read this list on every product rather than assuming which products carry them. Some add-ons apply only when the property has an accessory dwelling unit: pass has_adu=true to see those as well. Some add-ons are quoted by the appraisal management company rather than priced from a rate card. An order carrying one is placed with fees.appraisal_fee null until the company quotes it, and order.fee_changed tells you the price.
loan_purposesarray of string enumThe loan purposes this product may be ordered for. An empty list means the product takes any purpose. A purpose the product does not accept is refused with 422.
property_typesarray of string enumThe property types this product may be ordered for. An empty list means the product takes any type. A type the product does not accept is refused with 422.
OrderTypeList
FieldTypeDescription
datarequiredarray of OrderType
pagerequiredinteger
per_pagerequiredinteger
totalrequiredintegerHow many items match in total.
total_pagesrequiredinteger
BorrowerFields
The fields a borrower and a co-borrower share.
FieldTypeDescription
first_namerequiredstring
last_namerequiredstring
addressone ofThe borrower's own address, when it is not the property address.
receives_reportbooleanTrue to send the delivered report to this borrower.
receives_status_updatesbooleanTrue to send status updates to this borrower.
Borrower
FieldTypeDescription
first_namerequiredstring
last_namerequiredstring
addressone ofThe borrower's own address, when it is not the property address.
receives_reportbooleanTrue to send the delivered report to this borrower.
receives_status_updatesbooleanTrue to send status updates to this borrower.
rolerequiredstring
contactsrequiredarray of ContactPhone numbers and email addresses for the borrower. At least one is required. Either a phone number or an email address satisfies it; send a phone number where you have one, because that is how an appraiser arranges access.
CoBorrower
FieldTypeDescription
first_namerequiredstring
last_namerequiredstring
addressone ofThe borrower's own address, when it is not the property address.
receives_reportbooleanTrue to send the delivered report to this borrower.
receives_status_updatesbooleanTrue to send status updates to this borrower.
rolerequiredstring
contactsarray of ContactPhone numbers and email addresses for the co-borrower. Optional: the array may be empty or left out.
BorrowerOrCoBorrower
One person on the order. role says which of the two this is, and which rules apply: contacts are required on the borrower and optional on the co-borrower. An order carries one borrower and at most one co-borrower.
RealEstateAgent
The agent to contact for access, when there is one.
FieldTypeDescription
first_namestring or null
last_namestring or null
companystring or null
contactsarray of Contact
AdditionalContact
Someone else to copy. report receives the delivered report; status receives status updates.
FieldTypeDescription
purposerequiredstring enumOne of: report, status
namestring or null
emailrequiredstring (email)
Parties
Other people involved in the order.
FieldTypeDescription
real_estate_agentone of
additional_contactsarray of AdditionalContact
Note
A note on the order. order notes are general instructions; appointment notes are about arranging access. An order carries one note of each type. Notes have no ids and cannot be edited or removed through this interface.
FieldTypeDescription
typerequiredstring enumOne of: order, appointment
textrequiredstring
OrderFlags
The handling flags on the order.
FieldTypeDescription
rushbooleanThe lender is asking for a faster turn time. The appraisal management company decides whether a rush fee applies.
complexboolean
ruralboolean
priorityboolean
certified_appraiser_requiredbooleanTrue when only a certified appraiser may take the assignment.
LoanCreate
The loan the appraisal supports.
FieldTypeDescription
purposerequiredstring enumWhy the loan is being made. Send other with loan.purpose_other when nothing else fits.One of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance
purpose_otherstring or nullRequired when purpose is other.
numberstring or nullThe lender's loan number.
clientstring or nullThe client the lender is acting for, when it is not the lender itself.
investorstring or null
agency_case_numberstring or null
fha_case_numberstring or nullThe case number for the loan. Required when the product's appraiser_certification is fha_required or usda, accepted and not required when it is fha_optional, and not used when it is none.
purchase_pricestring or nullA decimal string with two places. Required when purpose is purchase.
currencystring or nullThe three letter currency code for the amounts on this order. Defaults to USD.
Loan
FieldTypeDescription
purposerequiredstring enumWhy the loan is being made. Send other with loan.purpose_other when nothing else fits.One of: construction_only, construction_to_permanent, mortgage_modification, other, purchase, refinance
purpose_otherstring or nullRequired when purpose is other.
numberstring or nullThe lender's loan number.
clientstring or nullThe client the lender is acting for, when it is not the lender itself.
investorstring or null
agency_case_numberstring or null
fha_case_numberstring or nullThe case number for the loan. Required when the product's appraiser_certification is fha_required or usda, accepted and not required when it is fha_optional, and not used when it is none.
purchase_pricestring or nullA decimal string with two places. Required when purpose is purchase.
currencystring or nullThe three letter currency code for the amounts on this order. Defaults to USD.
loan_typeone ofThe loan type tier the order was placed on, for a product on the current report standard.
add_onsarray of CatalogItemThe add-ons attached to the order.
PropertyCreate
The property to be appraised.
FieldTypeDescription
addressrequiredAddressA United States street address. Properties and territories of the United States only. postal_code is required. city, state and county are filled in from it when you leave them out, and the filled in values are returned on the order. Where a postal code covers more than one place name we store the postal service's preferred name. A postal code we cannot resolve is refused with 422.
typerequiredstring enumWhat kind of property is being appraised.One of: church, commercial_non_residential, condominium, condominium_over_four_stories, cooperative, farm, home_and_business_combined, manufactured_mobile_home, mixed_use_residential, multifamily_more_than_four_units, other, single_family, townhouse, two_to_four_unit_property, vacant_land
occupancyrequiredstring enumHow the property is occupied.One of: investment_property, primary_residence, second_home, vacant
has_adubooleanTrue when the property has an accessory dwelling unit. Some add-ons on the current report standard apply only when this is true.
Property
The property on an order, as it is read back.
FieldTypeDescription
addressrequiredAddressA United States street address. Properties and territories of the United States only. postal_code is required. city, state and county are filled in from it when you leave them out, and the filled in values are returned on the order. Where a postal code covers more than one place name we store the postal service's preferred name. A postal code we cannot resolve is refused with 422.
typerequiredstring enumWhat kind of property is being appraised.One of: church, commercial_non_residential, condominium, condominium_over_four_stories, cooperative, farm, home_and_business_combined, manufactured_mobile_home, mixed_use_residential, multifamily_more_than_four_units, other, single_family, townhouse, two_to_four_unit_property, vacant_land
occupancyrequiredstring enumHow the property is occupied.One of: investment_property, primary_residence, second_home, vacant
has_adubooleanTrue when the property has an accessory dwelling unit.
OrderCreate
An order to place. Read GET /order-types first: it gives you the order_type_code to send and, for a product on the current report standard, the loan_type_code and add_on_codes values that product accepts.
FieldTypeDescription
order_type_coderequiredstringThe product to order, from GET /order-types.
loan_type_codestring or nullThe loan type tier, from the product's loan_types. Required when the product lists loan types. An unknown or inapplicable code is refused with 422 rather than being guessed at.
add_on_codesarray of stringAdd-ons to attach, from the product's add_ons.
due_daterequiredstring (date)The date the lender needs the report by. The appraisal management company confirms or adjusts it.
lender_referencestring or nullYour own reference for this order. We store it and return it, and you can search on it.
rushboolean
complexboolean
ruralboolean
priorityboolean
certified_appraiser_requiredboolean
appraiser_instructionsstring or nullAccess instructions and anything else the appraiser needs to know.
loanrequiredLoanCreateThe loan the appraisal supports.
propertyrequiredPropertyCreateThe property to be appraised.
borrowersrequiredarray of BorrowerOrCoBorrowerThe borrower, and a co-borrower when there is one.
partiesPartiesOther people involved in the order.
notesarray of Note
documentsarray of InlineDocumentSupporting documents to attach at create, base64 encoded. Prefer POST /orders/{order_id}/documents for anything over a megabyte or two.
InlineDocument
A supporting document sent inside a JSON body.
FieldTypeDescription
kindstring
purposestring enumWhat a document you upload is for. Optional; other is assumed when you leave it out.One of: engagement_letter, sales_contract, prior_report, other
filenamerequiredstring
content_typerequiredstring
descriptionstring or null
datarequiredstringThe file's bytes, base64 encoded. The decoded size counts against the 25 MB limit.
OrderPatch
The parts of an open order a lender may change. Send only what changes. An empty body is refused with 400.
FieldTypeDescription
lender_referencestring or null
due_datestring (date)A REQUEST to move the due date. The date changes only when the appraisal management company accepts it.
appraiser_instructionsstring or null
loanobjectOnly the loan number, the client and the investor may be changed.
borrower_contactsarray of ContactReplaces the borrower's contact list. Names and the property cannot be changed.
partiesPartiesOther people involved in the order.
notesarray of NoteNotes to add to the order. An order carries one note of each type, and what you send is added to the note of that type rather than replacing it. Nothing already on the order is removed.
Fees
The fee the lender is charged. Read only through this API.
FieldTypeDescription
appraisal_feerequiredstring or nullThe fee the lender is charged, as a decimal string with two places. It is normally set when the order is created. It is null when the product or an add-on has to be quoted by the appraisal management company, and it can change later. Either way order.fee_changed tells you.
currencyrequiredstring
OrderDates
The dates on the order.
FieldTypeDescription
created_atrequiredstring (date-time)
updated_atrequiredstring (date-time)When anything you can see on the order last changed: its status, its dates, its fee, its documents, its messages or its own fields. This is the field updated_since filters on.
due_daterequiredstring (date)
appointment_atstring or null (date-time)The inspection appointment, when one has been scheduled.
completed_atstring or null (date-time)When the report was delivered.
AppraiserRef
The assigned appraiser, by display name only. It is present only where the appraisal management company shares the assigned appraiser with its lenders. Where it does not, appraiser is null.
FieldTypeDescription
namerequiredstring
Order
An order, as the lender sees it.
FieldTypeDescription
idrequiredstringOur id for the order. Always starts with ord_.
order_numberrequiredstringThe order number the appraisal management company uses, the one a person will quote on the phone.
lender_referencestring or null
statusrequiredOrderStatusA status, as a stable code with display text.
order_typerequiredOrderTypeRefThe product an order was placed against.
loanrequiredLoan
propertyrequiredPropertyThe property on an order, as it is read back.
borrowersarray of BorrowerOrCoBorrower
partiesPartiesOther people involved in the order.
notesarray of Note
flagsOrderFlagsThe handling flags on the order.
appraiser_instructionsstring or null
appraiserone of
datesrequiredOrderDatesThe dates on the order.
feesrequiredFeesThe fee the lender is charged. Read only through this API.
documentsarray of DocumentSummaryThe documents on the order, without download links.
OrderSummary
An order as it appears in a list.
FieldTypeDescription
idrequiredstring
order_numberrequiredstring
lender_referencestring or null
statusrequiredOrderStatusA status, as a stable code with display text.
order_typerequiredOrderTypeRefThe product an order was placed against.
property_address_summarystringThe property address on one line, for display.
datesrequiredOrderDatesThe dates on the order.
OrderList
FieldTypeDescription
datarequiredarray of OrderSummary
pagerequiredinteger
per_pagerequiredinteger
totalrequiredintegerHow many items match in total.
total_pagesrequiredinteger
ActionRequest
The reason for an action. The appraisal management company and the appraiser both see it.
FieldTypeDescription
reasonstring
OrderActionResult
The outcome of a hold, a resume or a cancellation.
FieldTypeDescription
idrequiredstring
order_numberrequiredstring
statusrequiredOrderStatusA status, as a stable code with display text.
previous_statusOrderStatusRefA status without a timestamp, used for a previous status.
RevisionKind
correction asks the appraiser to fix or clarify the report. reconsideration_of_value asks the appraiser to reconsider the opinion of value and requires at least one acknowledgement.

One of: correction, reconsideration_of_value

RevisionAcknowledgements
Required on a reconsideration of value. At least one must be true, or the request is refused with 422.
FieldTypeDescription
prior_appraisal_providedboolean
comparable_sales_providedboolean
RevisionRequestCreate
FieldTypeDescription
kindrequiredstring enumcorrection asks the appraiser to fix or clarify the report. reconsideration_of_value asks the appraiser to reconsider the opinion of value and requires at least one acknowledgement.One of: correction, reconsideration_of_value
reasonrequiredstringWhat needs to change, and why.
acknowledgementsRevisionAcknowledgementsRequired on a reconsideration of value. At least one must be true, or the request is refused with 422.
document_idsarray of stringDocuments already uploaded to this order that support the request.
documentsarray of InlineDocumentDocuments to attach inline instead of uploading first.
RevisionResponse
One reply on a revision request.
FieldTypeDescription
idrequiredstring
created_atrequiredstring (date-time)
authorrequiredAuthorWho wrote a message. People are identified by display name only.
messagerequiredstring
documentsarray of DocumentSummary
RevisionRequest
A correction or reconsideration on a delivered report.
FieldTypeDescription
idrequiredstringAlways starts with rr_.
order_idrequiredstring
kindrequiredstring enumcorrection asks the appraiser to fix or clarify the report. reconsideration_of_value asks the appraiser to reconsider the opinion of value and requires at least one acknowledgement.One of: correction, reconsideration_of_value
statusrequiredstring enumsubmitted while the appraisal management company reviews it, accepted once it is with the appraiser, declined when the company does not take it forward, and completed once a revised report has been delivered against it.One of: submitted, accepted, declined, completed
reasonrequiredstring
acknowledgementsRevisionAcknowledgementsRequired on a reconsideration of value. At least one must be true, or the request is refused with 422.
documentsarray of DocumentSummary
responsesarray of RevisionResponse
created_atrequiredstring (date-time)
updated_atrequiredstring (date-time)
RevisionRequestList
FieldTypeDescription
datarequiredarray of RevisionRequest
pagerequiredinteger
per_pagerequiredinteger
totalrequiredintegerHow many items match in total.
total_pagesrequiredinteger
Author
Who wrote a message. People are identified by display name only.
FieldTypeDescription
typerequiredstring enumOne of: lender, manager, appraiser, system
namerequiredstring
MessageCreate
FieldTypeDescription
recipientrequiredstring enumWho the message is for. A company that keeps appraiser contact in its own hands refuses appraiser with 422 and code recipient_not_allowed.One of: manager, appraiser
subjectstring or null
bodyrequiredstring
document_idsarray of stringDocuments already uploaded to this order to attach.
Message
A message on an order.
FieldTypeDescription
idrequiredstringAlways starts with msg_.
order_idrequiredstring
recipientrequiredstring enumWho the message was addressed to.One of: manager, appraiser, lender
subjectstring or null
bodyrequiredstring
authorrequiredAuthorWho wrote a message. People are identified by display name only.
attachmentsarray of DocumentSummary
created_atrequiredstring (date-time)
MessageList
FieldTypeDescription
datarequiredarray of Message
pagerequiredinteger
per_pagerequiredinteger
totalrequiredintegerHow many items match in total.
total_pagesrequiredinteger
DocumentKind
What a document is.
  • report_pdf: the appraisal report as a PDF.
  • report_data: the report data. On uad_2_6 it is the MISMO 2.6 GSE appraisal XML, with the report PDF embedded as that standard defines. On uad_3_6 it is the UAD 3.6 delivery package, a ZIP produced by the appraiser's forms software to the GSE UAD 3.6 specification, whose members are defined by that specification. The package is delivered exactly as the forms software produced it, so whether a copy of the report PDF sits inside it is that software's doing. Either way report_pdf is always delivered as its own file as well, and that is the copy to read.
  • invoice: the invoice for the order. Always a separate file, and never inside the package.
  • compliance_certificate: the compliance certificate.
  • borrower_certificate: the borrower delivery certificate.
  • ssr: a submission summary report from the collateral delivery portal.
  • review_report: a quality review report produced by the appraisal management company's own review process, when the company provides it to lenders. It is not something a lender orders through this API.
  • supporting: anything supplied to support the order, by either side.

One of: report_pdf, report_data, invoice, compliance_certificate, borrower_certificate, ssr, review_report, supporting

DocumentSummary
A document without a download link.
FieldTypeDescription
idrequiredstringAlways starts with doc_.
kindrequiredstring enumWhat a document is.
  • report_pdf: the appraisal report as a PDF.
  • report_data: the report data. On uad_2_6 it is the MISMO 2.6 GSE appraisal XML, with the report PDF embedded as that standard defines. On uad_3_6 it is the UAD 3.6 delivery package, a ZIP produced by the appraiser's forms software to the GSE UAD 3.6 specification, whose members are defined by that specification. The package is delivered exactly as the forms software produced it, so whether a copy of the report PDF sits inside it is that software's doing. Either way report_pdf is always delivered as its own file as well, and that is the copy to read.
  • invoice: the invoice for the order. Always a separate file, and never inside the package.
  • compliance_certificate: the compliance certificate.
  • borrower_certificate: the borrower delivery certificate.
  • ssr: a submission summary report from the collateral delivery portal.
  • review_report: a quality review report produced by the appraisal management company's own review process, when the company provides it to lenders. It is not something a lender orders through this API.
  • supporting: anything supplied to support the order, by either side.
One of: report_pdf, report_data, invoice, compliance_certificate, borrower_certificate, ssr, review_report, supporting
filenamerequiredstring
content_typerequiredstring
size_bytesinteger or null
descriptionstring or null
created_atrequiredstring (date-time)
Download
A signed link to the file. It is valid for five minutes and may be used more than once inside that window. Fetch a fresh link rather than storing one.
FieldTypeDescription
urlrequiredstring (uri)Follow it with a plain GET and no Authorization header: the signature in the link is the authorization. Its expires value is expires_at in Unix seconds.
expires_atrequiredstring (date-time)When the link stops working. Ask for another one after that.
Document
FieldTypeDescription
idrequiredstringAlways starts with doc_.
kindrequiredstring enumWhat a document is.
  • report_pdf: the appraisal report as a PDF.
  • report_data: the report data. On uad_2_6 it is the MISMO 2.6 GSE appraisal XML, with the report PDF embedded as that standard defines. On uad_3_6 it is the UAD 3.6 delivery package, a ZIP produced by the appraiser's forms software to the GSE UAD 3.6 specification, whose members are defined by that specification. The package is delivered exactly as the forms software produced it, so whether a copy of the report PDF sits inside it is that software's doing. Either way report_pdf is always delivered as its own file as well, and that is the copy to read.
  • invoice: the invoice for the order. Always a separate file, and never inside the package.
  • compliance_certificate: the compliance certificate.
  • borrower_certificate: the borrower delivery certificate.
  • ssr: a submission summary report from the collateral delivery portal.
  • review_report: a quality review report produced by the appraisal management company's own review process, when the company provides it to lenders. It is not something a lender orders through this API.
  • supporting: anything supplied to support the order, by either side.
One of: report_pdf, report_data, invoice, compliance_certificate, borrower_certificate, ssr, review_report, supporting
filenamerequiredstring
content_typerequiredstring
size_bytesinteger or null
descriptionstring or null
created_atrequiredstring (date-time)
order_idrequiredstring
downloadrequiredDownloadA signed link to the file. It is valid for five minutes and may be used more than once inside that window. Fetch a fresh link rather than storing one.
DocumentList
FieldTypeDescription
datarequiredarray of DocumentSummary
pagerequiredinteger
per_pagerequiredinteger
totalrequiredintegerHow many items match in total.
total_pagesrequiredinteger
DocumentPurpose
What a document you upload is for. Optional; other is assumed when you leave it out.

One of: engagement_letter, sales_contract, prior_report, other

DocumentUpload
A multipart upload. A document you upload is visible to the appraisal management company and to the assigned appraiser.
FieldTypeDescription
filerequiredstring (binary)The file. Up to 25 MB.
kindrequiredstringOnly supporting may be uploaded by a lender.
purposestring enumWhat a document you upload is for. Optional; other is assumed when you leave it out.One of: engagement_letter, sales_contract, prior_report, other
descriptionstringWhat the file is, for the appraiser.
DeliveryStatus
How delivery of an event to your endpoint is going.
  • pending: not yet attempted, or waiting for its next attempt.
  • delivered: your endpoint returned a 2xx.
  • failed: at least one attempt failed and another is scheduled.
  • dead_lettered: every attempt failed. We will not try again, and the event stays readable here.
  • not_subscribed: raised but not delivered, because your subscription does not include this type.

One of: pending, delivered, failed, dead_lettered, not_subscribed

EventDelivery
The delivery state of one event.
FieldTypeDescription
statusrequiredstring enumHow delivery of an event to your endpoint is going.
  • pending: not yet attempted, or waiting for its next attempt.
  • delivered: your endpoint returned a 2xx.
  • failed: at least one attempt failed and another is scheduled.
  • dead_lettered: every attempt failed. We will not try again, and the event stays readable here.
  • not_subscribed: raised but not delivered, because your subscription does not include this type.
One of: pending, delivered, failed, dead_lettered, not_subscribed
attemptsrequiredinteger
last_attempt_atstring or null (date-time)
next_attempt_atstring or null (date-time)
last_response_statusinteger or nullThe HTTP status your endpoint returned on the last attempt.
EventType
The event catalog.

One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed

Event
An event in your feed, with its delivery state.
FieldTypeDescription
idrequiredstringAlways starts with evt_. Ids are lexicographically sortable and come out in the order the events were raised. Compare them as strings; do not decode one.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)
order_idrequiredstringEvery event type in version 1 is an order event, so this is always set.
datarequiredobjectThe same payload we deliver to your endpoint for this event, without the envelope fields. Its schema is the one published under webhooks for this type.
deliveryrequiredEventDeliveryThe delivery state of one event.
EventList
A page of events. The feed uses a cursor: pass next_cursor back as after until it comes back null.
FieldTypeDescription
datarequiredarray of Event
next_cursorrequiredstring or nullPass this as after to read the next page. Null when you have reached the end.
WebhookConfig
Where we deliver your events.
FieldTypeDescription
urlrequiredstring (uri)
enabledrequiredboolean
eventsrequiredarray of stringThe event types you are subscribed to, or ["*"] for all of them.
secret_setrequiredbooleanTrue when a signing secret is set. The secret itself is never returned.
secret_rotated_atstring or null (date-time)
updated_atstring or null (date-time)
WebhookConfigUpdate
The fields you send are replaced. The fields you leave out keep their current values: omitting events keeps your subscription, and omitting secret keeps your secret. url is always required.
FieldTypeDescription
urlrequiredstring (uri)An HTTPS URL that answers a POST with a 2xx within 10 seconds.
enabledbooleanSend false to stop delivery without losing your configuration.
eventsarray of stringEvent types to subscribe to, or ["*"] for all of them. Leave it out to keep your current subscription.
secretstringSet or rotate the signing secret. At least 32 characters of random text. Never returned, and never cleared by this call: leave it out to keep the secret you have.
WebhookEnvelope
Every webhook body shares these fields. Branch on type, and use id to make your handler idempotent: a redelivery carries the same id.
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderRef
Every event payload carries at least these two fields.
FieldTypeDescription
order_idrequiredstring
order_numberrequiredstring
EventOrderCreated
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderStatusChanged
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderAssigned
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderOnHold
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderResumed
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderCancelled
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderCompleted
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderDocumentAdded
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderMessagePosted
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderRevisionRequested
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderRevisionResponded
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderDueDateChanged
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
EventOrderFeeChanged
FieldTypeDescription
idrequiredstringThe event id, the same value as X-AH-Event-Id.
typerequiredstring enumThe event catalog.One of: order.created, order.status_changed, order.assigned, order.on_hold, order.resumed, order.cancelled, order.completed, order.document_added, order.message_posted, order.revision_requested, order.revision_responded, order.due_date_changed, order.fee_changed
created_atrequiredstring (date-time)When we raised the event, not when we delivered it.
api_versionrequiredstringThe version of this contract the payload was built to.
testbooleanTrue only on a specimen event sent by POST /webhook/test. Never true on a real event, and a test event is not written to your feed. A specimen carries a synthetic data.order_id, always prefixed ord_test_, which no real order in any environment ever carries, so it can never match one of your orders. When test is true, verify the signature, answer 2xx, and stop: do not store the event and do not look the order up. This holds in production as well as in the sandbox.
datarequiredobject
Appraisal Host - Appraisal Management Software for AMCs and Lenders

Platform

  • Features
  • Integrations
  • Pricing

Solutions

  • For AMCs
  • For Lenders
  • For Appraisal Companies
  • For Non-QM Lenders
  • For Banks
  • For Credit Unions

Resources

  • Tools
  • Developers
  • Blog
  • FAQ
  • Support
  • Compliance & Regulations

Company

  • About
  • Contact

Appraisal Host

1 Washington Mall #1105

Boston, MA 02108

© 2026 Appraisal Host

|Privacy Policy|Terms of Service|SMS Consent

appraisalhost.com is a service of Appraisal Host LLC.

Powered byOptiWork.ai