ARUON Research — ordering by API and MCP

How a program or an AI agent orders an ARUON Research report. Every order goes through the same door as the order form on reir.aruon.ai, and the same people are in it.

Weekly maintenance: Tuesdays from 1:00 AM Central for up to about 45 minutes, reir.aruon.ai may not answer. Orders and payments are never lost; if a request fails then, retry after 1:45 AM Central.

What a program can and cannot do

Jobs we do

Each job is one report, ordered by its SKU (the MCP tool create_order, or POST https://reir.aruon.ai/api/hub/order). Prices in US dollars, from the catalog.

Pay with crypto

USDC on the Base network (mainnet) is the one cryptocurrency we accept: no other coin, token or network. One USDC counts as one US dollar. The buyer pays from the buyer's own wallet; no agent and no tool here moves money.

USDC amounts per report before tax (exact amount with a unique tag is given at checkout). Texas sales tax applies.:

1. The catalog and prices

GET https://reir.aruon.ai/pricing.json (the same file at https://reir.aruon.ai/.well-known/pricing.json): every report with sku, name, price_usd (null where the report is quoted), purchasable, instant_pay, requires_scope_review, turnaround, deliverable_summary, sample_url, order_url, terms_url, credit_rules, updated_at and catalog_version.

GET https://reir.aruon.ai/api/hub/catalog is the order page's own feed of the same catalog. While ordering is closed it answers ok: false with a reason and no products.

2. Check coverage

GET https://reir.aruon.ai/api/coverage/band?sku=<sku> plus ONE place: state and county_fips, or lat and lng, or zip, or address. It always answers HTTP 200; ok: false is a refusal with its reason. An address is up to 100 characters, and address lookups are limited to 30 per hour per connection.

FieldMeaning
bandfull_data (we hold the parcel record), zip_only (market data at ZIP grain), or unknown.
source_idThe parcel source that holds the county, or null.
source_labelThat source's name, or null.
zoning_screenedWhether zoning is screened in this county.
sla_hours24 where this report runs on the 24-hour clock here; otherwise null.
okfalse is a refusal: read reason.
reasonWhy, in a sentence.
area_scanFor the ring searches: the ordered ring is loaded (a source is registered and the ring is on disk).
area_sourceA bulk source is registered for the county.
area_loadedThe ring asked about is loaded.
ringThe ring the reading was asked about.
skuThe report the reading is for.
stateTwo-letter state.
county_fipsFive-digit county FIPS.
county_resolutionHow a ZIP, an address or a point became a county.
county_nameThe county's name.
opt_in_ringThe ring is the opt-in large ring (always quoted).
document_holdWhy the Property Screen is quoted in this county, when it is.
versionThe record's version.

A band other than full_data, or ok: false, means an analyst confirms scope before anything is charged.

3. Place an order

POST https://reir.aruon.ai/api/hub/order with a JSON body (Content-Type: application/json, up to 64 KiB). The fields:

FieldTypeRequiredMeaning
skustringyesThe report, by its catalog key (list_products / pricing.json). (one of: market_scan, scout_shortlist_founding, screen_parcel, market_report, tower_sheet, tower_targets, site_search)
full_namestringyesThe buyer's name.
emailstringyesThe buyer's email. The one confirmation and the report go here; it must be a deliverable address.
companystringnoThe buyer's company (optional).
phonestringnoThe buyer's phone (optional).
consentbooleanyestrue: the buyer accepts the Privacy Policy and the SMS terms. Required.
paid_ackbooleanyestrue: the buyer acknowledges, verbatim: “I understand this is a paid engagement. After payment, an ARUON analyst checks the order and starts the report; the clock starts at our analyst's go-ahead, not at the card charge.” Required.
geographyobjectyesONE place. kind=address: {address}; kind=zip: {zip}; kind=county: {state, county_fips}; kind=parcel: {state, county_fips, parcel_id}; kind=pin: {lat, lng} (saved as coordinates, never turned into an address).
usestringnoIntended use, for the SKUs that read one (Property Screen, Tower Sheet, Site Search). (one of: data_center, edge_data_center, cell_tower, storage_units, condo_development, multi_family, commercial_property, strip_mall_retail, mixed_use_development, industrial_warehouse, single_family, other)
notesstringnoAnything the analyst should read; longer text is cut at 4,000 characters. Read by a person; it changes nothing automatically.
asking_pricenumbernoThe asking price, where the report reads one (Property Screen, Housing Screen).
mustarraynoMust-have chips for the ring searches (Tower Sheet, Site Search): the catalog's hunt_chips keys; min_acres posts as min_acres=<n>.
nicearraynoNice-to-have chips, same keys. Emphasis only; they filter nothing.
radius_miintegernoSearch radius in whole miles, 1–100, for the ring searches. Blank is the default ring.
site_acresnumbernoSite size the buyer needs, in acres (read by the analyst).
min_acresnumbernoMinimum lot size in acres; it filters the search only when posted as a must-have.
ai_agent_namestringnoThe agent placing the order. (up to 120 characters)
agent_operatorstringnoThe organisation that runs the agent. A person checks the first order from an operator before its report is released. (up to 120 characters)
on_behalf_ofstring or objectnoThe principal the agent orders for: a name, or {name, organization, email}.

Send only these fields. website is reserved: it is the order form's bot trap, and an order that carries it is dropped without notice. The server reads the price, the coverage band and the payment mode itself; a posted price or band is ignored.

Search radius: whole miles, 1–100. A geography the server cannot place, a ZIP that does not exist, a missing field or an invalid email is refused with HTTP 400 before anything is written.

{
  "sku": "market_report",
  "full_name": "Pat Buyer",
  "email": "pat@example.com",
  "consent": true,
  "paid_ack": true,
  "geography": {
    "kind": "zip",
    "zip": "01027"
  },
  "ai_agent_name": "Example buying agent",
  "agent_operator": "Example Agents Inc",
  "on_behalf_of": {
    "name": "Pat Buyer",
    "organization": "Buyer Co"
  }
}

HTTP 202 means the order is filed:

FieldMeaning
oktrue
tokenThe order token: the order's secret. Keep it; the status and the order page read it.
modepay (instant pay, a checkout link) or scope (an analyst confirms scope first).
pay_urlThe HubSpot checkout link, only when mode is pay; otherwise null.
bandThe coverage band the server read for this order (see the coverage check).
sla_hours24 where the order runs on the 24-hour clock (The clock starts at our analyst's go-ahead, not at the card charge.); otherwise null.
statusThe order record's status (awaiting_payment or awaiting_approval).
agent_statusThe same status in the words below (Status words).
request_idThe order number.
skuThe report ordered.
labelThe report's name.
price_lineThe price as the catalog prints it, or null where the report is quoted.
order_urlThe order page, /order/<token>. A bearer link: anyone who has it can read the order and pay for it, so keep it private.
noteWhy the order is on the scope path, or how it was placed, when there is something to say; otherwise null.

Refusals: HTTP 400 {ok: false, reason, errors}; HTTP 413 when the body is too large; HTTP 429 {ok: false, reason} past a rate limit; HTTP 500 {ok: false, status: "error", message, reason, correlation_id} when the fault is ours. Quote the correlation_id if you write to us.

4. Read an order's status

GET https://reir.aruon.ai/api/hub/order/<token> answers the order's record; an unknown token is HTTP 404 {ok: false, error: "not found"}. The order page /order/<token> shows the same record. The token is the order's secret; the buyer's email is masked. The order link in the buyer's order email is a bearer link: anyone who has it can read the order and pay for it, so keep it private.

FieldMeaning
oktrue
tokenThe order token.
request_idThe order number.
statusThe order record's status.
agent_statusThe same status in the words below (Status words).
modepay or scope, as the order was taken.
skuThe report ordered.
labelThe report's name.
bandThe coverage band read when the order was taken.
sla_hours24 or null, as above.
email_maskedThe buyer's email, masked (ab…@example.com).
pay_urlThe checkout link while the order awaits payment; otherwise null.
created_atWhen the order was taken (ISO 8601, UTC).
paid_atWhen HubSpot recorded the payment, or null.
go_atWhen an analyst gave the go-ahead (the clock's start), or null.
payment_notePresent only once a USDC payment has started on an order awaiting payment: why pay_url is null. One payment per order: the card link is withdrawn.
payment_statePresent with payment_note: where the USDC payment stands, {state, status, head, line, why, next, words}. status is the status word (held while a person at ARUON reviews it); line is the status in a phrase, why the reasons in plain words (or null), next what happens next, and words all three. The MCP tools' meaning is words.

5. Status words

agent_status (and the MCP tools' status) is one of:

StatusMeaning
awaiting_paymentInstant pay: finish checkout at checkout_url. Nothing runs before payment. Work begins at our analyst's go-ahead.
awaiting_scope_reviewAn analyst confirms scope with the buyer first, then sends the payment link or an invoice. Nothing is charged until then.
awaiting_human_approvalAn order filed before 2026-11-04 from an agent operator we had not approved yet: a person approves it before any checkout link. Nothing is charged until then.
paidPaid. The clock starts at our analyst's go-ahead, not at the card charge.
in_productionThe report is being built.
in_reviewThe report is built and an analyst is reading it before release.
deliveredReleased by an analyst and sent to the buyer's email.
heldA person at ARUON is looking at the order. Nothing is charged or sent until they act.
receivedReceived.
closedClosed. No report will be sent on this order.

6. The MCP server

https://reir.aruon.ai/mcp speaks the Model Context Protocol over streamable HTTP: one JSON-RPC message per POST, answered as JSON (a notification gets HTTP 202 and no body). It offers tools only, keeps no session and opens no stream: GET and DELETE answer 405. Protocol versions: 2025-11-25, 2025-06-18, 2025-03-26. A request may carry no Origin header or this site's own; any other is refused (HTTP 403).

It is listed in the official MCP Registry as io.github.Aruon-AI/reir: https://registry.modelcontextprotocol.io/v0/servers?search=io.github.Aruon-AI%2Freir. No sign-in: add https://reir.aruon.ai/mcp as a remote MCP server (streamable HTTP) in any client that takes one.

ToolWhat it doesRead-only
list_productsList products and pricesyes
check_coverageCheck coverage for a placeyes
create_orderPlace an order (nothing is charged here)no — files an order
get_order_statusGet an order's statusyes
start_crypto_paymentPay an order by crypto instead of the card linkno — files an order
confirm_crypto_paymentConfirm the buyer's code and get the crypto quoteno — files an order
request_new_quoteGet a new crypto quote after the last one expiredno — files an order

Every tool calls the same code as the HTTP endpoints above: list_products returns the pricing.json records, check_coverage the coverage record, create_order files the order through the order door and returns {order_token, status, checkout_url} (checkout_url only for awaiting_payment), and get_order_status reads the status record. create_order requires ai_agent_name and agent_operator. No tool charges, starts or releases anything.

list_products — input

{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}

check_coverage — input

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "sku"
  ],
  "description": "ONE place: state + county_fips, lat + lng, zip, or address.",
  "properties": {
    "sku": {
      "type": "string",
      "enum": [
        "market_scan",
        "scout_shortlist_founding",
        "screen_parcel",
        "market_report",
        "tower_sheet",
        "tower_targets",
        "site_search"
      ],
      "description": "The report the coverage is read for."
    },
    "state": {
      "type": "string",
      "description": "Two-letter state (with county_fips)."
    },
    "county_fips": {
      "type": "string",
      "description": "Five-digit county FIPS."
    },
    "place_fips": {
      "type": "string",
      "description": "Optional place FIPS."
    },
    "lat": {
      "type": "number"
    },
    "lng": {
      "type": "number"
    },
    "zip": {
      "type": "string",
      "description": "A five-digit ZIP (its primary county)."
    },
    "address": {
      "type": "string",
      "description": "A street address (geocoded once; address lookups are limited per connection)."
    }
  }
}

create_order — input

{
  "type": "object",
  "properties": {
    "sku": {
      "type": "string",
      "enum": [
        "market_scan",
        "scout_shortlist_founding",
        "screen_parcel",
        "market_report",
        "tower_sheet",
        "tower_targets",
        "site_search"
      ],
      "description": "The report, by its catalog key (list_products / pricing.json)."
    },
    "full_name": {
      "type": "string",
      "description": "The buyer's name."
    },
    "email": {
      "type": "string",
      "description": "The buyer's email. The one confirmation and the report go here; it must be a deliverable address."
    },
    "company": {
      "type": "string",
      "description": "The buyer's company (optional)."
    },
    "phone": {
      "type": "string",
      "description": "The buyer's phone (optional)."
    },
    "consent": {
      "type": "boolean",
      "description": "true: the buyer accepts the Privacy Policy and the SMS terms. Required."
    },
    "paid_ack": {
      "type": "boolean",
      "description": "true: the buyer acknowledges, verbatim: “I understand this is a paid engagement. After payment, an ARUON analyst checks the order and starts the report; the clock starts at our analyst's go-ahead, not at the card charge.” Required."
    },
    "geography": {
      "type": "object",
      "description": "ONE place. kind=address: {address}; kind=zip: {zip}; kind=county: {state, county_fips}; kind=parcel: {state, county_fips, parcel_id}; kind=pin: {lat, lng} (saved as coordinates, never turned into an address).",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "zip",
            "county",
            "parcel",
            "pin",
            "address"
          ]
        },
        "address": {
          "type": "string"
        },
        "zip": {
          "type": "string"
        },
        "state": {
          "type": "string"
        },
        "county_fips": {
          "type": "string"
        },
        "parcel_id": {
          "type": "string"
        },
        "lat": {
          "type": "number"
        },
        "lng": {
          "type": "number"
        }
      },
      "required": [
        "kind"
      ]
    },
    "use": {
      "type": "string",
      "enum": [
        "data_center",
        "edge_data_center",
        "cell_tower",
        "storage_units",
        "condo_development",
        "multi_family",
        "commercial_property",
        "strip_mall_retail",
        "mixed_use_development",
        "industrial_warehouse",
        "single_family",
        "other"
      ],
      "description": "Intended use, for the SKUs that read one (Property Screen, Tower Sheet, Site Search)."
    },
    "notes": {
      "type": "string",
      "description": "Anything the analyst should read; longer text is cut at 4,000 characters. Read by a person; it changes nothing automatically."
    },
    "asking_price": {
      "type": "number",
      "description": "The asking price, where the report reads one (Property Screen, Housing Screen)."
    },
    "must": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Must-have chips for the ring searches (Tower Sheet, Site Search): the catalog's hunt_chips keys; min_acres posts as min_acres=<n>."
    },
    "nice": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Nice-to-have chips, same keys. Emphasis only; they filter nothing."
    },
    "radius_mi": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "Search radius in whole miles, 1–100, for the ring searches. Blank is the default ring."
    },
    "site_acres": {
      "type": "number",
      "minimum": 0,
      "description": "Site size the buyer needs, in acres (read by the analyst)."
    },
    "min_acres": {
      "type": "number",
      "minimum": 0,
      "description": "Minimum lot size in acres; it filters the search only when posted as a must-have."
    },
    "ai_agent_name": {
      "type": "string",
      "maxLength": 120,
      "description": "The agent placing the order."
    },
    "agent_operator": {
      "type": "string",
      "maxLength": 120,
      "description": "The organisation that runs the agent. A person checks the first order from an operator before its report is released."
    },
    "on_behalf_of": {
      "description": "The principal the agent orders for: a name, or {name, organization, email}.",
      "anyOf": [
        {
          "type": "string",
          "maxLength": 200
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string"
            },
            "organization": {
              "type": "string"
            },
            "email": {
              "type": "string"
            }
          }
        }
      ]
    }
  },
  "required": [
    "sku",
    "full_name",
    "email",
    "consent",
    "paid_ack",
    "geography",
    "ai_agent_name",
    "agent_operator"
  ],
  "additionalProperties": false
}

get_order_status — input

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "order_token"
  ],
  "properties": {
    "order_token": {
      "type": "string",
      "description": "From create_order."
    }
  }
}

start_crypto_payment — input

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "order_token",
    "rail",
    "billing",
    "role",
    "wallet_address",
    "accept",
    "accept_terms"
  ],
  "properties": {
    "order_token": {
      "type": "string"
    },
    "rail": {
      "type": "string"
    },
    "billing": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "line1",
        "city",
        "postal",
        "country"
      ],
      "properties": {
        "line1": {
          "type": "string"
        },
        "line2": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "region": {
          "type": "string"
        },
        "postal": {
          "type": "string"
        },
        "country": {
          "type": "string"
        }
      }
    },
    "role": {
      "type": "string",
      "enum": [
        "investor",
        "broker",
        "carrier",
        "developer",
        "other"
      ]
    },
    "wallet_address": {
      "type": "string"
    },
    "phone": {
      "type": "string",
      "description": "The buyer's phone. Required here when the order was placed without one."
    },
    "accept": {
      "type": "boolean",
      "description": "The buyer accepts the terms, the refund policy and the privacy policy for this payment, and this acknowledgment (hub-ack-2026-11-02-crypto): \"I understand this is a paid engagement. After payment, an ARUON analyst checks the order and starts the report; the clock starts at our analyst's go-ahead, not at payment (the card charge or the USDC payment).\""
    },
    "accept_terms": {
      "type": "boolean",
      "description": "Must be true: the buyer has read and accepts Schedule C (Crypto Payments) of ARUON's Terms of Service, version 2026-11-06.1: https://aruon.ai/terms-of-service#schedule-c. Required before the code is emailed and before any payment; a call without it is refused and nothing is filed."
    }
  }
}

confirm_crypto_payment — input

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "order_token",
    "code"
  ],
  "properties": {
    "order_token": {
      "type": "string"
    },
    "code": {
      "type": "string"
    }
  }
}

request_new_quote — input

{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "order_token"
  ],
  "properties": {
    "order_token": {
      "type": "string"
    }
  }
}

7. Agent fields

8. Limits

LimitValue
Orders per connection (IP address)5 per hour
Orders per agent operator5 per hour
MCP requests per connection300 per hour
Address lookups on the coverage check30 per hour per connection
Request body (orders, MCP)64 KiB
Emaila deliverable mailbox address of up to 254 characters

9. Terms and policies