---
title: "Guest Business Suggest"
method: GET
path: "/v1/guest/business/suggest"
tags: ["guest"]
---

# Guest Business Suggest

`GET /v1/guest/business/suggest`

"What is your business called" — ASKED BEFORE THERE IS A WORKSPACE.

── THE MEASUREMENT THAT PUT THIS HERE ─────────────────────────────────────

Filmed on the door at 393x852 on 2026-09-03, typing "Eldorado Forklift" one
character at a time, from the first keystroke to the first row on screen:

    gate      +94ms  ->  +854ms      760ms
    workspace +864ms -> +3189ms     2325ms   <- the wait
    suggest  +3192ms -> +3928ms      736ms
                                    ------
                                    4055ms

The owner said *"now its a bit slow in typing + searching"*, and the search
is 18% of what he was waiting for. 57% of it is a workspace being minted —
canonical rows and a `git init` — that the typeahead does not need and
never did. `StartDoor` parks every keystroke until the mint lands
(`deferredSuggest`), so the FIRST answer on the first screen of the product
could not arrive before a repository had been created on disk.

── WHY THIS IS ALLOWED TO BE PUBLIC ───────────────────────────────────────

The team-scoped twin (`routers/geo.py :: business_suggest`) reads nothing
that belongs to a team. It asks Google about businesses that are on Google
Maps, and it now also reads a directory of businesses that is shared by
every workspace we have (`runtime/business_directory.py`). There was never
a tenant boundary being enforced here, only a credential being required —
and requiring one is what cost 2.3 seconds.

So the workspace stops being a prerequisite and goes back to being what it
is: the thing the person gets when they PICK a row. The mint still fires on
the first keystroke, still in parallel; it simply no longer stands in front
of the answer.

── WHAT STANDS BETWEEN THIS AND THE PLACES BILL ───────────────────────────

1. `stormy_guest_play`, the same switch as the mint: the door being shut
   shuts this too, because a typeahead into a closed product is only a way
   to spend money.
2. The Supabase directory in front of Google. A phrase that has been asked
   in the last six hours costs nothing at all, which is most of the volume
   an abuser would generate.
3. A per-address window, above.
4. Two characters minimum, ten rows maximum — the same caps the team route
   carries.

No Turnstile. The mint keeps the one challenge in this product, and putting
a second one in front of a keystroke would be paid for by every real person
on the screen this route exists to make fast.

## Query parameters

- `query` string
- `limit` integer
- `region` string
- `near_lat` number, nullable
- `near_lng` number, nullable

## Headers

- `authorization` string, nullable
- `x-darwin-token` string, nullable

## Response `200`

Successful Response

- object

## Other responses

- `422` — Validation Error

## Changes

> 33 revisions in range; 1 not diffed.

- **2026-09-26** `faea4a09e09c` — 2 info
  - added the new optional `header` request parameter `authorization`
  - added the new optional `header` request parameter `x-darwin-token`
- **2026-09-04** `cb4b3e1a2e37` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/stormy/apis/stormy-control-plane/changes/v1/guest/business/suggest/get.md)

---

[API](https://skmtc.dev/stormy/apis/stormy-control-plane.md) · [All operations](https://skmtc.dev/stormy/apis/stormy-control-plane/llms.txt) · [OpenAPI document](https://skmtc.dev/stormy/apis/stormy-control-plane/revisions/52151384d62a?raw)
