---
name: showfirst-websites
description: Build and manage websites for local businesses with ShowFirst. Build a full website for one business, make one-page preview sites for a whole list or search, check builds, change a finished website and undo changes, and make Online Presence Report links to pitch with. Use when the user asks to build, preview, check, edit or pitch a website for a local business with ShowFirst.
---

# ShowFirst websites

ShowFirst builds websites for local businesses, usually the leads an agency found with a ShowFirst search. You can use it two ways:

- **MCP tools**, if ShowFirst is connected as an MCP server: `list_designs`, `lookup_business`, `build_website`, `website_status`, `list_websites`, `create_preview_batch`, `list_preview_batches`, `get_preview_batch`, `restyle_preview_batch`, `update_preview`, `export_preview_batch`, `create_report`, `read_website`, `change_website`, `undo_website_change`, `check_credits`.
- **REST API**, with curl or any HTTP client: everything under `/api/websites/` and `/api/reports`.

The two do the same thing with the same credits. Use MCP tools when they are available; otherwise use the REST calls below.

## The rule that matters

Building uses the user's credits. Nothing is spent until you confirm.

1. Send the build or batch **without** `confirm` first. Nothing starts. The reply has a `plan` with the cost (`website_credits_needed`, and for a batch `batch_sites_from_plan`) and the balance.
2. Tell the user in plain words, for example "This builds one website for Harbor Plumbing and uses 1 of your 3 website credits."
3. Wait for a clear yes. Then send the same request with `"confirm": true`.

Never confirm on the user's behalf. Ask before removing anything from a website.

## Setup

- **Base URL:** `https://showfirst.app`. If the user's dashboard is on their own domain, use that domain instead.
- **API key:** the user makes one in their ShowFirst dashboard under **API Keys**. Ask them to put it in an environment variable rather than pasting it into chat:

```bash
export SHOWFIRST_API_KEY=sf_live_your_key
```

Send it on every request as `Authorization: Bearer $SHOWFIRST_API_KEY` (or as an `x-api-key` header).

## What things cost

| What | Cost |
|---|---|
| A website | 1 website credit, given back if the build fails |
| A preview batch | 1 batch site per business, at least 5. A plan's monthly batch sites are used first, then website credits. Given back only if no preview gets built. |
| Everything else: designs, lookups, status, lists, restyling, editing, undo, reports | Free. Editing works while the account has editor credits. |

## Build one website

```bash
# 1. Pick a design (no key needed)
curl -s https://showfirst.app/api/websites/designs

# 2. Plan it: nothing is spent
curl -s -X POST https://showfirst.app/api/websites \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY" -H "content-type: application/json" \
  -d '{"business_name": "Harbor Plumbing", "design": "bold", "city": "Sarasota", "state": "FL"}'

# 3. After the user says yes: the same body with "confirm": true
curl -s -X POST https://showfirst.app/api/websites \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY" -H "content-type: application/json" \
  -d '{"business_name": "Harbor Plumbing", "design": "bold", "city": "Sarasota", "state": "FL", "confirm": true}'
```

Only `business_name` is required. Useful extras: `phone`, `email`, `website` (their current site), `address`, `industry`, `about`, `services`, `service_areas`, `hours`, `brand_color` (hex), `logo_url`, `language`.

**From a search:** send `"from_search": {"job_id": "...", "place_id": "..."}` instead of typing the details. The business's name, phone, email, website, address and category come from that search; anything you also send wins.

**From Google:** `GET /api/websites/business-lookup?name=Harbor%20Plumbing&city=Sarasota` returns matches and a `lookup_session`. Ask which one is right, call again with `place_id` and the same `lookup_session` for the details, then build with `google_place_id`.

The confirmed build returns a `website_id`. Check it every 15 to 30 seconds:

```bash
curl -s https://showfirst.app/api/websites/WEBSITE_ID -H "Authorization: Bearer $SHOWFIRST_API_KEY"
```

`status` goes `queued`, `building`, `preview_ready` (the `preview_url` works now), `finishing`, `done`. `failed` means it did not build and the credit came back. A build takes several minutes. `GET /api/websites` lists every website on the account.

If a build call fails or times out, check `GET /api/websites` before trying again, so you never build twice.

## Preview sites for a whole list

A preview batch makes a one-page preview site for every business, to pitch many leads at once.

```bash
# Plan from a finished search: businesses with no website only
curl -s -X POST https://showfirst.app/api/websites/batches \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY" -H "content-type: application/json" \
  -d '{"industry": "Plumbing", "design": "night", "from_search": {"job_id": "JOB_ID", "has_website": false}}'
```

Or send `"businesses": [{"business_name": "...", "phone": "...", "email": "...", "address": "..."}]` (up to 500; a `google_place_id` per business fills the rest from Google). Tell the user the plan, then send the same body with `"confirm": true`.

| Do | Call |
|---|---|
| Every preview link | `GET /api/websites/batches/BATCH_ID` |
| A spreadsheet for a cold email tool | `GET /api/websites/batches/BATCH_ID/results?format=csv` |
| Change the batch colour, background, logo size | `PATCH /api/websites/batches/BATCH_ID` with `brand_color`, `background`, `logo_size` |
| Fix one preview | `PATCH /api/websites/batches/BATCH_ID/previews/PREVIEW_ID` with `business_name`, `phone`, `email`, `address`, `logo_url`, `brand_color` or `background` (null clears) |
| All batches | `GET /api/websites/batches` |

## Pitch with an Online Presence Report

```bash
curl -s -X POST https://showfirst.app/api/reports \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY" -H "content-type: application/json" \
  -d '{"job_id": "JOB_ID", "place_id": "PLACE_ID", "website_url": "https://the-preview-you-built.example/"}'
```

The reply's `report_url` is a page the user can send the business owner: how the business shows up online next to its top local competitors. It shows public facts only. Asking again for the same business gives the same link.

## Change a finished website (MCP tools)

Editing a built website is done with three MCP tools:

1. `read_website` with `what: "guide"` first: it explains how the site is built and the rules.
2. Find before you change: `read_website` with `what: "find_text"` and a `query`, or `what: "fields"`, `"pages"`, `"design"`, `"images"`, `"forms"`, `"collection"`.
3. `change_website` with a `change` such as `fields`, `add_page`, `add_service`, `seo`, `colors`, `menu`, `image`, `forms`, `add_item` (a review or FAQ). Changes go live right away and return a `change_id`.
4. `undo_website_change` with that `change_id` undoes it; with a `version_id` from `read_website` (`what: "versions"`) it restores the whole site. Undo newest first.

A change that takes longer returns `status: "pending"` and an `edit_id`; check it with `read_website`, `what: "edit_result"`.

Not available from a chat: uploading new images, AI-written pages and AI images, and fonts. Those are in the dashboard editor.

## Errors

| Status | Meaning |
|---|---|
| 400 | Something in the request is wrong. `details` lists each problem by field name. Nothing was spent. |
| 401 | The key is missing, unknown or revoked. |
| 403 | Not enough credits, the plan has no batch sites, or the key is not linked to an account. Nothing was spent. |
| 404 | Unknown ID, or it belongs to another account. |
| 503 | Building is under maintenance, or Google lookup is not available. Try again later. |

A build may answer `paused: true`: builds are paused for now and nothing was spent. Try again later.

Docs: https://showfirst.app/docs/api-websites, https://showfirst.app/docs/mcp, https://showfirst.app/openapi.json
