HelpRent Da Nang

ベトナム・ダナンのすべての長期賃貸物件:検索、建物、中央値の家賃。鍵もアカウントも不要。

ドキュメント

The whole board, as a tool call

Every long-term rental in Da Nang — 9479 of them right now — is readable by machine: prices, districts, sizes and the nightly market medians. No key, no account, no signup, nothing to scrape. Past the free allowance a caller pays per call in stablecoins, without a human in the loop.

Try it here

This runs a real MCP call from your browser against the live endpoint. Nothing is mocked.

MCP

One stateless JSON-RPC endpoint. Protocol revision 2026-07-28, so there is no initialize handshake and no session to keep.

https://helprentdanang.com/mcp/

Four tools, all read-only:

  • search_listings — Search long-term rental listings in Da Nang by city, district, type, bedrooms and price. Returns listing URLs; contact details are not included, send the person to the URL.
  • get_listing — One listing in full, including its description.
  • find_buildings — Apartment buildings with a manager, by district.
  • market_stats — Median rents by size and district, the middle half of asking prices with the sample behind each figure, and how many listings are on the board. Recomputed nightly.

There is no write tool. Nothing here creates a lead, saves a search or hands out contact details, so there is no call an agent could make on someone's behalf that would need approving.

Plain HTTP

The same data, if you would rather not speak MCP. OpenAPI description at the last line.

  • GET /api/v1/listings/ — search and page through listings
  • GET /api/v1/listings/<slug>/ — one listing in full
  • GET /api/v1/buildings/ — apartment buildings with a manager
  • GET /api/v1/districts/ — districts and how much is in each
  • GET /api/v1/market/ — median rents, recomputed nightly
  • GET /api/v1/openapi.json — the description of all of the above

Limits

600 calls a day per address, counted across MCP and REST together. That is a server-cost ceiling, not a secret — it is set generously enough that an agent working through the city's inventory never meets it. Nothing is ever banned.

Past the line both surfaces answer 402 with a payment challenge, described below. Every response carries your remaining free allowance, so you never have to find the ceiling by hitting it:

  • X-RateLimit-Limit — the daily allowance
  • X-RateLimit-Remaining — how much of it is left
  • X-RateLimit-Reset — unix time when it refills

Responses carry a five-minute cache header. Please honour it — it is most of what keeps this free.

What is in the data

Listings are gathered from public posts on Telegram, Facebook and Chợ Tốt, plus hosts who post here directly. Each carries its price where the original stated one, its district, and a link back to the source. Contact details are deliberately not in the API — send the person to the listing URL.

We are a board, not a broker. We do not verify owners on the ground, hold deposits, or vouch for anyone. An agent relaying our data to a person should relay that too.

Past the free line

Beyond the daily allowance the endpoints answer 402 with an x402 payment challenge instead of a flat refusal. Pay it and the same request goes through.

It is x402, the HTTP 402 payment protocol, exact scheme. One challenge carries two entries in its accepts array, USDC on Base and USDC on Solana, and your client picks the chain it already holds funds on. Three headers, all base64 JSON:

  • PAYMENT-REQUIRED — our 402 carries this header: base64 JSON naming the amount, the token and the address
  • PAYMENT-SIGNATURE — retry with this header: your signed EIP-3009 authorization on Base, or your partially signed transaction on Solana
  • PAYMENT-RESPONSE — the 200 that follows carries the transaction hash back to you

Note the header names carry no X- prefix — that was version 1, and a client built for it will not see our challenge at all.

One payment buys 5000 calls, not one — settling on chain per request would put a blockchain write between you and every listing you read.

Bought calls are credited to the calling address, not to the wallet that paid, because this API has no accounts and no keys — on the request after a payment there is nothing else tying you to that wallet. If your egress address changes, the remainder does not follow you.

What we accept

[
  {
    "scheme": "exact",
    "network": "eip155:8453",
    "amount": "10000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0xf68bc1098469356eb57e70db9fed0bb524707132",
    "maxTimeoutSeconds": 60,
    "extra": {
      "name": "USD Coin",
      "version": "2"
    }
  },
  {
    "scheme": "exact",
    "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
    "amount": "10000",
    "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "payTo": "6J7dpvZu4f3vYcRd3TY7dpjXZSYCRdLVfXkxtv3Ycz3j",
    "maxTimeoutSeconds": 60,
    "extra": {
      "feePayer": "CjNFTjvBhbJJd2B5ePPMHRLx1ELZpa8dwQgGL727eKww"
    }
  }
]

The accepts array as the 402 sends it, rendered from the same function, so this page cannot fall behind the challenge. Pick one entry and pay it; the challenge is complete enough to pay from without reading this page.

A real 402, end to end

# 1. over the free line, no payment attached
curl -i https://helprentdanang.com/mcp/ \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQQVlNRU5U...
cache-control: no-store

# 2. decode the header to see what is being asked for
echo '<that value>' | base64 -d | jq .

# 3. sign what your chosen entry describes (EIP-3009 on Base, a partially
#    signed transaction on Solana), then repeat the SAME request
curl -i https://helprentdanang.com/mcp/ \
  -H 'Content-Type: application/json' \
  -H 'PAYMENT-SIGNATURE: <base64 of your PaymentPayload>' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

HTTP/2 200
payment-response: eyJzdWNjZXNzIjp0cnVlLCJ0cmFuc2FjdGlvbiI6IjB4...

Read-only, and that is a decision

There is no write tool and there never has been. Nothing here creates a lead, saves a search, sends a message or spends money on anyone's behalf, so there is no call on this server that needs a human to approve it. Every tool carries readOnlyHint and destructiveHint in its annotations, which is how your host knows that without taking our word for it.

Contact details are never returned — not a phone number, not a WhatsApp link, not the source URL that would resolve to one, and not inside a listing description either. An agent can read everything about a place and sends its person to our page to reach the poster. That page is rate-limited, logged, and carries the warning about viewing before paying; a contact handed out through an API arrives with none of that attached.

Stored free text is treated as untrusted on the way out: a listing description is a post a stranger wrote, and serving it raw would make us the delivery mechanism for an injection into your agent.