API Reference

Partner API Reference

Everything you need to integrate the two core partner flows — Submit (you collect consent and file directly) and Handoff (Andy finishes with the customer for you). Every example below was captured against the live sandbox.

Sandbox base URLhttps://api-andyv2.andyreach.com
Production base URLhttps://api.theandyapp.com
Authenticationx-api-key: <your key>

Overview

The Andy Partner API lets you check a property for tax-protest savings and then either file the protest yourself or hand the customer to Andy to finish. All requests are JSON over HTTPS and are authenticated with a per-partner API key. Start in sandbox — submissions there are simulated and never filed with a real appraisal district.

 SandboxProduction
Base URLapi-andyv2.andyreach.comapi.theandyapp.com
Gateway path/api/partner-service (address lookup uses /api/property-service)
Real filings?No — simulatedYes — filed with the appraisal district
Auth headerx-api-key

Authentication

Every request must include your secret key in the x-api-key header. Keys are issued per partner and per environment. Treat the key like a password — never embed it in browser or mobile code; call the API from your server.

HTTP header
x-api-key: sk_sandbox_your_key_here
Content-Type: application/json
Keep keys server-side. If a key is ever exposed, contact techsupport@theandyapp.com to rotate it immediately.

The two flows

Both flows begin the same way — find the address and get an estimate — then diverge at the final step.

Submit flow You collect consent & file
  1. 1 Autocomplete find the address
  2. 2 Estimate check savings, get estimate_id
  3. 3 Submit consent + signature → reference_id
  4. 4 Status track the case
Handoff flow Andy finishes with the customer
  1. 1 Autocomplete find the address
  2. 2 Estimate check savings, get estimate_id
  3. 3 Handoff send customer details → handoff_id
POST/api/property-service/real-estate/autocompleteproperty-service

Address Autocomplete

Returns matching property addresses for a partial search string. Use it to help a user pick a precise address before requesting an estimate. Optional — you may also pass any full address string straight to /estimate.

Request body

FieldTypeRequiredDescription
searchstringrequiredPartial or full address the user has typed (min. 3 characters).
search_typesstring[]requiredResult categories to include. A = address, P = parcel, C = city, G = geo, N = name, T = tract, Z = ZIP.
Request
curl -X POST 'https://api-andyv2.andyreach.com/api/property-service/real-estate/autocomplete' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: sk_sandbox_your_key_here' \
  -d '{
    "search_types": ["A","P","C","G","N","T","Z"],
    "search": "3706 Robinson Ave, Austin"
  }'
Response200 OK
{
  "status": "success",
  "message": "Property detail retrieved successfully",
  "data": {
    "input": { "search_types": ["A"], "search": "3706 Robinson Ave, Austin" },
    "data": [
      {
        "address": "3706 Robinson Ave, Austin, TX, 78722",
        "city": "Austin",
        "zip": "78722",
        "county": "Travis County",
        "searchType": "A",
        "title": "3706 Robinson Ave, Austin, TX, 78722"
      }
    ],
    "totalResults": 1,
    "returnedResults": 1
  }
}
POST/api/partner-service/estimatepartner-service

Get Savings Estimate

Checks whether a property qualifies for a tax protest and returns the estimated savings and property details. The returned estimate_id is required by both /submit and /handoff.

Request body

FieldTypeRequiredDescription
addressstringrequiredFull property address to evaluate, e.g. "3706 Robinson Ave, Austin, TX, 78722".
Request
curl -X POST 'https://api-andyv2.andyreach.com/api/partner-service/estimate' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: sk_sandbox_your_key_here' \
  -d '{ "address": "3706 Robinson Ave, Austin, TX, 78722" }'
Response200 OK
{
  "estimate_id": "EST68B8A2CAC6BFC35B",
  "eligible": true,
  "estimated_savings": 2586.87,
  "property": {
    "address": "3706 Robinson Ave",
    "county": "Travis County",
    "assessed_value": 707568.0,
    "market_value": 882000.0,
    "tax_amount": 14371.51
  }
}

Note: When a property is not eligible, eligible is false, estimated_savings is 0, and the property value fields are null.

POST/api/partner-service/submitpartner-service

Submit Protest

Files a property tax protest on the owner's behalf. Requires the owner's recorded consent and electronic signature. Returns a reference_id used to track the case with /status.

Request body

FieldTypeRequiredDescription
estimate_idstringrequiredThe id returned by /estimate.
ownerobjectrequiredOwner details: first_name, last_name, email, phone.
property_typestringrequired"residential" or "commercial".
consentobjectrequiredConsent record: accepted (true), timestamp (ISO 8601), ip, version.
signaturestringrequiredOwner's electronic signature as a base64 PNG data URI.
documentsobject[]optionalOptional supporting files: each { url, type } where type is SUPPORTING_DOCUMENT or APPRAISAL.
sourcestringoptionalFree-form label identifying your integration, e.g. "partner_app".
Request
curl -X POST 'https://api-andyv2.andyreach.com/api/partner-service/submit' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: sk_sandbox_your_key_here' \
  -d '{
    "estimate_id": "EST68B8A2CAC6BFC35B",
    "owner": {
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane.smith@example.com",
      "phone": "+15122345678"
    },
    "property_type": "residential",
    "consent": {
      "accepted": true,
      "timestamp": "2026-08-25T10:00:00.000Z",
      "ip": "203.0.113.1",
      "version": "v1"
    },
    "signature": "data:image/png;base64,iVBORw0KGgo...",
    "documents": [
      { "url": "https://your-s3-url.com/doc.pdf", "type": "SUPPORTING_DOCUMENT" }
    ],
    "source": "partner_app"
  }'
Response200 OK
{
  "reference_id": "REF9A08F1E7FC5DC8",
  "status": "SUBMITTED",
  "message": "Your protest has been successfully filed"
}
GET/api/partner-service/statuspartner-service

Get Protest Status

Returns the current status of a previously submitted protest, including the assigned case id once the filing is processed.

Query parameters

FieldTypeRequiredDescription
reference_idstringrequiredQuery parameter — the id returned by /submit.
Request
curl 'https://api-andyv2.andyreach.com/api/partner-service/status?reference_id=REF9A08F1E7FC5DC8' \
  -H 'x-api-key: sk_sandbox_your_key_here'
Response200 OK
{
  "reference_id": "REF9A08F1E7FC5DC8",
  "case_id": "CASEAC8EDE46496EEA9A",
  "status": "FILED"
}

Note: status progresses through values such as SUBMITTED and FILED as the protest is processed.

POST/api/partner-service/handoffpartner-service

Handoff to Andy

Hands the customer off to Andy instead of collecting consent and signature yourself. You send minimal customer details; Andy completes consent, signature, and documents directly with the customer. Returns a handoff_id.

Request body

FieldTypeRequiredDescription
estimate_idstringrequiredThe id returned by /estimate.
customerobjectrequiredCustomer details: first_name, last_name, email (required), phone (optional).
property_typestringoptional"residential" or "commercial".
consent_to_contactobjectrequiredConsent to be contacted by Andy: accepted (true), timestamp, ip, version.
sourcestringoptionalFree-form label identifying your integration.
Request
curl -X POST 'https://api-andyv2.andyreach.com/api/partner-service/handoff' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: sk_sandbox_your_key_here' \
  -d '{
    "estimate_id": "EST68B8A2CAC6BFC35B",
    "customer": {
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane.smith@example.com",
      "phone": "+15122345678"
    },
    "property_type": "residential",
    "consent_to_contact": {
      "accepted": true,
      "timestamp": "2026-08-25T10:00:00.000Z",
      "ip": "203.0.113.1",
      "version": "v1"
    },
    "source": "partner_app"
  }'
Response200 OK
{
  "handoff_id": "HND_MTA3BHAXUVJEYW1A",
  "estimate_id": "EST68B8A2CAC6BFC35B",
  "status": "HANDOFF_INITIATED",
  "expires_at": "2026-09-02T12:48:54.109882Z",
  "message": "Customer link generated. Redirect the customer or send via email."
}

Errors

Errors return the matching HTTP status and a JSON body of the shape { "code": "…", "message": "…" }. The most common cases:

HTTPCodeMeaning
400INVALID_INPUTA required field is missing or malformed.
401INVALID_API_KEYThe x-api-key header is missing, wrong, or revoked.
404NOT_FOUNDThe referenced resource (e.g. reference_id) does not exist.
422CONSENT_REQUIREDconsent.accepted / consent_to_contact.accepted was not true.
429RATE_LIMITEDYou exceeded the request rate limit for your key.
5xxINTERNAL_ERRORAn unexpected server error — safe to retry with backoff.
When contacting support, include the environment, endpoint, HTTP status, the code field, a UTC timestamp, and any estimate_id or reference_id involved — never a raw API key.

Ready to try it?

Run the whole flow end-to-end against the live sandbox — no real filings are made.