> ## Documentation Index
> Fetch the complete documentation index at: https://docs.letshum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool reference

> Inputs, outputs, statuses, errors, side effects, and recovery rules for Hum's four MCP tools

# Tool reference

Hum Broadband MCP version `2.0.1` returns schema-version 4 objects with snake\_case field names.
All tool inputs are closed: unknown fields and unsupported field combinations are rejected.

Download the [released contract export](/mcp/contracts/released-contract.json) for the complete
`tools/list` descriptions, JSON Schemas, runtime input-shape rules, and release provenance. The
[scenario fixtures](/mcp/examples/scenarios.json) contain the synthetic examples used by these
pages.

This reference is frozen to `letshum/hum-mcp` commit
`cd74ba9583c1c245638fa100a914f9cf85372dc7`.

<Info>
  JSON Schema describes each field, while the runtime shape rules below describe which fields may be
  sent together. A field being optional in a generated schema does not make every combination valid.
</Info>

## `check_availability`

Resolves an address and combines FCC area evidence with live provider qualification. It is
read-only and idempotent for the same continuation.

### Accepted input shapes

| Purpose | Exact fields |
| - | - |
| Start | `{address}` |
| Select a candidate | `{candidate_id}` |
| Select a candidate and supply its requested unit | `{candidate_id, unit}` |
| Poll a lookup | `{lookup_id}` |
| Answer the current question set | `{lookup_id, question_set_id, answers}` |

| Field | Type | Meaning |
| - | - | - |
| `address` | string, 1–300 characters | Complete U.S. service address in natural language. |
| `candidate_id` | string, 1–2,048 characters | Opaque candidate returned by Hum. Do not parse or edit it. |
| `unit` | string, 1–100 characters | Unit requested for the chosen candidate. It is invalid without `candidate_id`. |
| `lookup_id` | string, 1–256 characters | Opaque lookup used for polling or the current question set. |
| `question_set_id` | string, 1–256 characters | Exact current question set returned for this lookup. |
| `answers` | object | Keys and value types must match the returned questions. Send the required set together. |

### Availability result

| Field | Type | Meaning |
| - | - | - |
| `schema_version` | integer | `4`. |
| `status` | enum | `checking`, `needs_information`, `complete`, `failed`, or `error`. |
| `lookup_id` | string or null | Capability for polling, answering questions, and selecting an offer. |
| `revision` | integer or null | Current lookup revision. A non-error result with a lookup ID includes a revision. |
| `expires_at` | timestamp or null | When the lookup or its returned capabilities expire. |
| `normalized_address` | object or null | Display address plus street, unit, city, state, and postal code. |
| `sources` | object or null | Separate `fcc` and `live_provider_check` state. |
| `providers` | array or null | Provider evidence, informational plans, and executable offers. |
| `candidates` | array or null | Up to five address choices. Each has `candidate_id`, `display`, and `requires_unit`. |
| `clarification_type` | enum or null | `candidate_selection` or `unit_required`. |
| `required_field` | enum or null | Currently `unit` when a unit is required. |
| `message` | string or null | Safe explanation for the current state. |
| `question_set_id` | string or null | Current question-set identity. |
| `questions` | array | Typed qualification questions. |
| `retry_after_seconds` | integer or null | Minimum wait before polling. |
| `warnings` | string array | Limits or partial-result warnings that must remain visible. |
| `next_action` | string or null | Safe next step for this result. |
| `error` | object or null | Structured tool-result error when `status` is `error`. |

Each source has `status`, `checked_at`, `data_as_of`, and an optional structured `error`. Source
status is `checking`, `needs_information`, `complete`, `failed`, or `timed_out`.

Each question has a `question_id`, `prompt`, `type`, optional `choices`, `required`, and
`sensitivity`. Question types are `string`, `boolean`, `single_choice`, and `date`.

### Provider, plan, and offer fields

| Object | Fields and rules |
| - | - |
| Provider | `provider_id`, `name`, `provenance`, optional `fcc_match`, `qualification_status`, `orderable_through_hum`, `offers`, and `catalog_plans`. |
| FCC match | `granularity` is `census_block` or `census_tract`; `data_as_of` can be null. |
| Plan facts | Name, technology, download/upload Mbps, pricing, fees, contract terms, data limit, and conditions. Unknown commercial facts remain null. |
| Catalog plan | Informational plan facts with no executable offer capability. |
| Offer | Plan facts plus `offer_id`, `provider_id`, `qualification_revision`, `qualified_at`, `expires_at`, and `orderable_through_hum: true`. |

Hum serializes these public commercial facts through a closed allowlist. Internal provider data,
private rate identifiers, upstream transaction identifiers, and customer or contact values are not
included in plan or offer objects, validation reviews or change comparisons, or order receipts.

Money and fee amounts are integer cents with a three-letter currency code. Do not infer a regular
price, promotion length, installation fee, equipment fee, contract, speed, or data limit when its
field is null.

See [Availability and offers](/mcp/availability-and-offers) for presentation rules.

## `validate_order`

Creates or resumes a draft for one executable offer, collects the fields required by that offer,
refreshes its facts, and returns an exact review. It is non-destructive and idempotent for the same
draft state. It creates no order and sends no fulfillment request.

### Accepted input shapes

| Purpose | Exact fields |
| - | - |
| Start validation | `{lookup_id, offer_id}` |
| Poll or refresh a checkout | `{checkout_id}` |
| Supply requested details | `{checkout_id, expected_revision, details}` |

| Field | Type | Meaning |
| - | - | - |
| `lookup_id` | string | Lookup that returned the executable offer. |
| `offer_id` | string | Exact current server-returned offer ID. |
| `checkout_id` | string | Opaque checkout capability returned by validation. |
| `expected_revision` | integer | Current revision returned for the checkout. Prevents stale updates. |
| `details` | object | Changed customer, installation, consent, and equipment fields Hum requested or returned. These belong inside `details`, never at the tool root. |

`details.customer` can contain first name, last name, email, phone number, a four-digit service PIN,
date of birth, billing preferences, and a mailing address. `details.installation` can contain an
installation type, desired service start date, and first and second preferred date/time windows.
`details.consents` maps returned consent keys to booleans. `details.internet_addons` is the complete
equipment selection, expressed as returned option IDs and positive integer quantities.

Installation type is `self` or `professional`. A preferred installation date contains both a
date and one of these exact local-time windows:

* `8:00 AM - 12:00 PM (Local Time)`
* `12:00 PM - 5:00 PM (Local Time)`

When preferred dates are required, provide both `first` and `second`. Billing preferences are
`details.customer.preferences.paperless_billing` and `details.customer.preferences.auto_pay`.
Send an explicit boolean for each requested preference; these fields are not payment authorization.

When Hum requests a mailing-address choice, send
`details.customer.mailing_address.same_as_service`. If it is `false`, also send `line1`, `city`,
`state`, and `postal_code` together; `line2` remains optional.

The selected provider determines which fields are required. Do not assume that a PIN, birth date,
installation choice, preference, mailing address, or consent is universal. Hum never requests card
data, Social Security numbers, existing-account passwords, or payment authorization through this
tool.

### Equipment selection

Validation can return up to 100 `equipment_options`:

| Field | Meaning |
| - | - |
| `option_id` | Opaque server-returned option identity. Return it unchanged. |
| `name` | Customer-facing equipment name. |
| `selection_type` | `radio` or `checkbox`. Select at most one radio option. |
| `included` | Whether the option is included in the returned cart. |
| `unit_pricing` | Amount in integer cents and a three-letter currency. |
| `max_quantity` | Highest permitted quantity. |
| `selected_quantity` | Quantity in the current cart or defaults. |

Each `details.internet_addons` item contains only `option_id` and a positive integer `quantity`.
Send the complete desired selection. Omit the field to retain the current selection or initial
defaults; send `[]` to decline optional equipment. Dependent options can appear after their parent
is selected, so retain the parent when sending the next complete selection. Never send a price,
SKU, or private catalog identifier.

Customer-owned equipment, included provider equipment, and optional paid equipment are different
choices. A free provider gateway does not meet a customer-owned equipment request. Use returned
option names and catalog facts to check ownership; price or `included` status alone cannot prove
it. If the offer lacks the requested option, inspect another qualified offer or ask the customer
to choose. An empty option list alone does not prove the ISP has no equipment.

### Validation result

| Field | Type | Meaning |
| - | - | - |
| `schema_version` | integer | `4`. |
| `checkout_id` | string or null | Capability for all later validation, submission, and retrieval calls. |
| `revision` | integer or null | Current draft revision. |
| `status` | enum | `checking`, `needs_information`, `ready`, `offer_changed`, `unavailable`, `expired`, `failed`, or `error`. |
| `required_fields` | string array | Checkout field definitions. This list can include paths already filled. |
| `field_errors` | object | Actual missing or invalid fields mapped to safe correction messages; paths are relative to `details`. |
| `equipment_options` | array | Current public equipment choices, pricing, defaults, and quantity limits. |
| `review` | object or null | Exact offer and customer-facing terms to present before authorization. |
| `terms_hash` | string or null | Digest that binds authorization to the returned review. |
| `validation_token` | string or null | Opaque token authorizing submission of the validated review. |
| `expires_at` | timestamp or null | Expiry for the ready validation. Revalidate after expiry. |
| `retry_after_seconds` | integer or null | Minimum wait before polling a checking draft. |
| `next_action` | string or null | Required next step. |
| `error` | object or null | Structured tool-result error when `status` is `error`. |

Use exactly one input shape: start with `lookup_id` and `offer_id`; poll with only `checkout_id`;
edit with `checkout_id`, the current `expected_revision`, and changed fields inside `details`.
While `checking`, wait at least `retry_after_seconds` before polling. Sending an edit while polling
increments the revision and restarts validation. After a stale-revision error, retrieve the
checkout with only `checkout_id`, wait if it is still checking, then edit at the returned revision.
Starting again with the same lookup and offer returns the existing draft.

`required_fields` is the contract definition, not a list of everything the customer must answer
again. Use `field_errors` for actual missing or invalid values and reuse facts already supplied.
For example, `consents.privacy_policy` in `field_errors` is sent as
`details.consents.privacy_policy` in an edit. If no specific field error is returned, do not assume
every `required_fields` path is missing or invent a value.

| Validation status | Next step |
| - | - |
| `checking` | Wait for the returned delay; poll with only `checkout_id`. |
| `needs_information` | Correct actual `field_errors` using the current revision. Do not assume every `required_fields` path is missing. |
| `ready` | Check the review against the customer's request, present it, and obtain authorization for the current terms. |
| `offer_changed` | Present previous and current offer/cart facts; return to fresh availability after the customer's decision. |
| `unavailable` | Start fresh availability and inspect current offers. Do not infer that the provider cannot serve the address. |
| `expired` | Revalidate the current checkout; if the offer expired, run availability again. Obtain new authorization. |
| `failed` | Start fresh availability before another attempt. If failure recurs, explain the limit and stop retrying. |
| `error` | Follow the safe error and `next_action`, including retrieve-before-edit for a stale revision. |

### Review shapes

A ready validation returns a closed `review` object:

| Field | Meaning |
| - | - |
| `provider_name` | Public provider name. |
| `selected_offer` | Current plan facts, including pricing, fees, contract terms, data limit, and conditions. |
| `included_products` | Included internet, television, and television add-on line items with quantities and pricing. These are returned cart contents, not a separate bundle-selection interface. |
| `one_time_fees` | Named one-time fee line items with descriptions, pricing, and fee types. |
| `total_amount` | Current total amount in integer cents and its currency. |
| `bundle_discount` | Returned cart discount, or null. Clients cannot invent or configure it. |
| `service_address` | Display address and unit. |
| `installation` | Returned installation type, desired start date, and preferred windows, or null. |
| `billing_preferences` | Returned paperless-billing and automatic-payment preferences, or null. These are preferences, not payment authorization. |
| `consents` | Provider consent keys and the reviewed boolean values. |
| `unknown_charges_remain_unknown` | Always `true`; the review does not convert unknown charges to zero. |

An `offer_changed` validation returns `previous_offer`, `current_offer`, and a non-empty
`changed_fields` list instead. When the cart changed, it can also return `previous_cart` and
`current_cart`, each with the selected plan, included products, one-time fees, total amount, and
optional bundle discount. Present the complete comparison and obtain a fresh decision before
continuing.

Reviews do not contain the customer's name, contact details, mailing address, service PIN, or date
of birth. Present the review returned by the current revision; do not reconstruct it from earlier
availability data.

Distinguish the plan's monthly price, recurring equipment charges, one-time fees, discounts, and
the returned cart total. The total is not necessarily the recurring monthly bill or payment due
now. Do not count an offer fee and an overlapping cart line twice. Preserve explicit auto-pay and
paperless-billing opt-outs; if no resulting price adjustment was returned, that adjustment is
unknown. Requested installation dates are preferences, not confirmed appointments. `ready` proves
technical validity, not that the cart matches the customer's budget, speed, equipment, billing,
and installation requirements. Keep PINs, full birth dates, hashes, tokens, and checkout IDs out
of customer-facing prose.

## `create_order`

Commits a ready validation after the host has presented the exact review and obtained the user's
authorization. This tool has a side effect and is marked destructive. Its idempotency key makes an
identical replay refer to the same intended submission; it is not permission to retry an uncertain
network outcome blindly.

### Accepted input shape

```json theme={null}
{
  "checkout_id": "checkout_example_01",
  "validation_token": "validation_example_01",
  "idempotency_key": "order-attempt-example-01",
  "confirmation": {
    "terms_hash": "terms_example_01",
    "confirmed": true
  }
}
```

| Field | Type | Meaning |
| - | - | - |
| `checkout_id` | string | Ready checkout capability. |
| `validation_token` | string | Token from the same ready revision and review. |
| `idempotency_key` | string, 1–128 characters | Stable identity for this exact intended order. |
| `confirmation.terms_hash` | string | Exact hash from the review the user authorized. |
| `confirmation.confirmed` | boolean literal | Must be `true` after authorization. |

The checkout, validation token, terms hash, and idempotency key must agree. A new key does not make
a second order safe. After a timeout, disconnect, or lost response, call `get_order` first.

## `get_order`

Reads the latest persisted order and fulfillment evidence. It is read-only and idempotent.

### Accepted input shape

```json theme={null}
{
  "checkout_id": "checkout_example_01"
}
```

`get_order` uses the opaque checkout ID, not the displayable order number.

## Order result

`create_order` and `get_order` return the same order-envelope type.

| Field | Type | Meaning |
| - | - | - |
| `schema_version` | integer | `4`. |
| `order_id` | string or null | Displayable Hum order reference. It does not authorize retrieval. |
| `status` | enum | `queued`, `submitting`, `accepted_by_fulfillment`, `rejected_by_fulfillment`, `submission_unknown`, `not_submitted`, or `error`. |
| `submitted_at` | timestamp or null | Recorded submission time when known. |
| `last_checked_at` | timestamp or null | When Hum last checked the fulfillment evidence. |
| `provider_name` | string or null | Public provider name. |
| `selected_offer_summary` | object or null | Non-sensitive plan facts for the selected offer. |
| `evidence` | object or null | Evidence `kind` and `recorded_at` timestamp. |
| `next_action` | string or null | Required follow-up or reconciliation step. |
| `error` | object or null | Structured tool-result error when `status` is `error`. |

See [fulfillment states](/mcp/ordering-and-recovery#fulfillment-states) before displaying a status.

## Errors

Hum can reject a malformed MCP request before a tool runs. Unsupported root fields, mixed input
shapes, and other input-schema violations can produce MCP `INVALID_PARAMS`, with no tool result or
side effect. Malformed nested `validate_order.details` instead returns a tool response marked
`isError` with safe field paths and constraints, without echoing submitted values or unsupported
field names. This nested tool error is not a structured business result with `status: "error"`.

A tool-result error uses `status: "error"` and this structure:

| Field | Meaning |
| - | - |
| `code` | Stable safe category: `invalid_request`, `invalid_address`, `invalid_answer`, `not_found`, `expired`, `offer_changed`, `offer_unavailable`, `validation_required`, `confirmation_required`, `idempotency_conflict`, `duplicate_order`, `rate_limited`, or `temporarily_unavailable`. |
| `message` | Safe human-readable explanation. |
| `retryable` | Whether the operation class can be retried under the returned guidance. |
| `retry_after_seconds` | Minimum delay when a retry is permitted. |
| `field_errors` | Optional field-specific correction messages. |
| `next_action` | Required next step. |
| `correlation_id` | Safe identifier to include in a support request. |

`retryable: true` does not override create-order recovery. If a create response is uncertain, call
`get_order` first and follow its persisted `status` and `next_action`.

## Expiry and processing limits

| Resource or operation | Released limit |
| - | - |
| Address candidate | 10 minutes |
| Lookup | 10 minutes; accepted answers and revision advances renew it |
| Executable offer | 15 minutes |
| Ready validation | 5 minutes |
| Draft | 24 hours |
| Checkout read capability | 90 days |
| Availability or validation work | 90 seconds per attempt |
| Returned poll guidance | 3 seconds when supplied; follow the current response |
| Accepted duplicate screening | 24 hours; unresolved matching submissions remain blocked |
| Sensitive fields after `submission_unknown` | At most 30 days; definitive outcomes purge them earlier |

These limits do not reserve provider inventory or guarantee that an offer, price, or serviceability
result will remain unchanged. Revalidate after an expiry and follow the returned next action.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.