Docs ← Back to dashboard
Start free Get API key

Websites API

The Websites API builds websites for local businesses: a full website for one business, or a one-page preview site for every business in a list or in one of your searches. It also checks builds, changes previews, makes Online Presence Report links and takes your clients' website requests. It runs the same builds as the dashboard and uses the same credits.

Every route is also in the API reference and in the OpenAPI file.

Using an AI agent? The MCP server has the same operations as tools, plus tools to change a finished website, and the websites skill teaches coding agents to use them.


Base URL

Send requests to the same domain you use for your dashboard. Every path on this page is relative to it.

Authentication

Send your API key as a bearer token on every request:

text
Authorization: Bearer YOUR_API_KEY

You can also send the key in an x-api-key header instead. Both work on every path on this page. To make a key, open API Keys in your dashboard, type a name in the Key label box, and click + Create New Key. The full key is shown once. Treat it like a password.

Client requests use a white-label agency key, which starts with sf_agency_. Everything else uses an account key.

Websites and batches belong to your account: any of your keys can read them, and so can the dashboard.


Plan first, then confirm

A build or a preview batch answers first with a plan: what it will make and what it costs. Nothing starts and nothing is spent. Send the same request again with "confirm": true to start it.

What things cost

WhatCost
A website1 website credit. Given back if the build fails.
A preview batch1 batch site per business, at least 5. Your plan's monthly batch sites are used first, then website credits. Given back only if no preview in the batch gets built.
Designs, Google lookup, status, lists, restyling, changing a preview, reportsFree.

Endpoints

MethodPathWhat it does
GET/api/websites/designsThe designs, with a picture of each. No key needed.
GET/api/websites/business-lookupFind a business on Google, then get its details.
POST/api/websitesPlan or build a website.
GET/api/websitesYour websites, newest first.
GET/api/websites/{websiteId}A build's progress and preview link.
POST/api/websites/batchesPlan or start a preview batch.
GET/api/websites/batchesYour preview batches, newest first.
GET/api/websites/batches/{batchId}One batch and every preview link.
PATCH/api/websites/batches/{batchId}Restyle a batch.
GET/api/websites/batches/{batchId}/resultsThe previews as JSON, a CSV, or format=ghl for a GoHighLevel import with each preview link.
PATCH/api/websites/batches/{batchId}/previews/{previewId}Change one preview.
POST/api/websites/requestsSave a client's website request (agency key).
GET/api/websites/requests/{requestId}Check a client's request (agency key).
POST/api/reportsMake an Online Presence Report link.

Build a website

Only business_name is required. Pick a design from the designs list; left out, the site uses classic.

bash
curl -X POST https://YOUR_DASHBOARD_DOMAIN/api/websites \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY" \
  -H "content-type: application/json" \
  -d '{"business_name": "Harbor Plumbing", "design": "bold", "city": "Sarasota", "state": "FL"}'

The plan:

json
{
  "ok": true,
  "requires_confirmation": true,
  "plan": { "business_name": "Harbor Plumbing", "design": "bold",
            "website_credits_needed": 1, "website_credits_left": 3 },
  "next": "Nothing has started. Send the same request with confirm: true to build it."
}

Send the same body with "confirm": true. The answer is 202 with a website_id:

json
{ "ok": true, "started": true, "website_id": "0c9b8a52-3d0e-4f7e-9d1d-2a6c7e1b5f10",
  "status": "queued", "preview_url": null, "website_credits_used": 1, "website_credits_left": 2 }

Fields

FieldWhat it is
business_nameBusiness name. Required unless from_search is sent.
designclassic, bold, night, angle or waterline.
phone, email, websiteContact details and their current website.
addressFull address, or just a town or service area. Or the parts: street, city, state, postal_code, country_code.
show_street_addressfalse hides the street address and postal code.
industry, aboutWhat the business does, and a few sentences about it.
services, service_areasLists of services and towns served.
hoursOpening hours as text.
google_place_idFrom the Google lookup. Name, address, phone and hours come from Google.
brand_color, logo_urlSix-digit hex colour, and a direct link to a logo.
languageen, es, fr, de, it, ro or tr.
from_search{"job_id", "place_id"}: one business from one of your finished searches. Its details fill the build; anything you also send wins.

Check a build

bash
curl https://YOUR_DASHBOARD_DOMAIN/api/websites/WEBSITE_ID \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY"

Check every 15 to 30 seconds. status goes queued, building, preview_ready (the preview_url works from here), finishing and done. failed means it did not build and the credit came back. A build takes several minutes.

Find a business on Google

bash
curl "https://YOUR_DASHBOARD_DOMAIN/api/websites/business-lookup?name=Harbor%20Plumbing&city=Sarasota" \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY"

The answer lists matches and a lookup_session. Call again with the chosen place_id and the same lookup_session for the business's address, phone, hours and website, then build with google_place_id.


Preview batches

A preview batch makes a one-page preview site for every business, up to 500, to pitch many leads at once. Send businesses, or from_search with a finished search's job_id:

bash
curl -X POST https://YOUR_DASHBOARD_DOMAIN/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}}'

from_search also takes has_email, has_phone and max_businesses. Each business in businesses takes business_name, google_place_id or google_cid, phone, email, address, website, hours, brand_color and logo_url. The whole batch takes industry, design, brand_color, background (light or dark), logo_size (48 to 160) and language.

The plan shows businesses, batch_sites_from_plan and website_credits_needed. Send the same body with "confirm": true to start; the answer has the batch_id.

GET /api/websites/batches/{batchId} lists every preview with its preview_url. Add /results?format=csv for the spreadsheet the dashboard's Export button gives.

bash
curl -X PATCH https://YOUR_DASHBOARD_DOMAIN/api/websites/batches/BATCH_ID/previews/PREVIEW_ID \
  -H "Authorization: Bearer $SHOWFIRST_API_KEY" \
  -H "content-type: application/json" \
  -d '{"phone": "(941) 555-0102"}'

That changes one preview. null clears a field. To restyle the whole batch, PATCH /api/websites/batches/{batchId} with brand_color, background, logo_size or (before it is built) language; previews with their own colour or background keep it.


Online Presence Reports

A report shows a business owner how they show up online next to their top local competitors. Make one for any business from one of your finished searches:

bash
curl -X POST https://YOUR_DASHBOARD_DOMAIN/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://your-preview.example/"}'

The answer's report_url is a page you can send. It shows public facts only, never the owner's contact details. website_url is optional: a website you built for them, shown on the report. Asking again for the same business gives the same link; "new_link": true makes a new one. Free.


Client requests

For agencies that take website requests from their own clients. With an agency key, POST /api/websites/requests takes the same fields as a build, plus client_email (required; saved as the business email, we never write to it) and build_now. Without build_now, the request waits for Approve on your API Keys page, and the website credit is used then. GET /api/websites/requests/{requestId} shows the approval and the build's progress.


Errors

Errors have "ok": false and an error. Validation errors also have details, one line per problem, by field name.

StatusMeaning
400Something in the request is wrong. Nothing was started or spent.
401The key is missing, unknown or revoked.
403Not enough credits, your plan has no batch sites, or the key is not linked to an account. Nothing was spent.
404Unknown ID, or it belongs to another account.
409A batch's language can only change before it is built.
503Building is under maintenance, or Google lookup is not available. Nothing was spent.

A build can also answer "paused": true: builds are paused for now. Nothing was queued or spent; try again later.