Enquiry form
Quotes, maintenance requests, or both. Up to 6 photos. In your colours, and it fits any space.
<div data-cete="enquiry-form"></div>
The enquiry form, website chat and client portal, on your own site, in minutes. Every enquiry and chat lands in CETECommand, ready to quote.
Quotes, maintenance requests, or both. Up to 6 photos. In your colours, and it fits any space.
<div data-cete="enquiry-form"></div>
A chat button in the corner. You answer from the app. Gone before you reply? Your answer reaches them by email.
data-chat
A Client login link. Customers sign in with their email to see their jobs, approve quotes and pay invoices.
<div data-cete="client-login"></div>
Each one takes a few minutes. Replace YOUR_BOOKING_KEY with the key from Website code, or copy the code straight from the app.
Use the CETECommand plugin. No code to paste, and it keeps working when you change themes.
Keep it as a .zip file. WordPress wants it that way.
In your WordPress dashboard: Plugins›Add New Plugin›Upload Plugin. Choose cetecommand.zip, press Install Now, then Activate.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
Then in WordPress go to Settings›CETECommand. Paste your booking key (the data-key from Website code) into Booking key. Tick Website chat for a chat button on every page, then press Save Changes. Leave CETECommand address as it is.
Edit your Contact page, add a Shortcode block and paste this:
[cete_enquiry_form][cete_enquiry_form type="work_order"]
[cete_enquiry_form type="quote" service="Roofing" title="Get a quote"]Optional. Use these anywhere: a page, a sidebar or the footer.
[cete_chat_button label="Chat with us"]
[cete_client_login label="Client login"]Contact Form 7, WPForms and Elementor Pro forms can send their entries to CETECommand too. In Settings›CETECommand, paste an API key (in CETECommand: Jobs›Settings›API and webhooks, Make a key) into API key. Tick your form plugin under Send entries from, pick quote or maintenance requests under Send them as, and press Save Changes. Test the API key checks it works. The key stays on your server.
Rather not use a plugin? Paste the one-line script from Any other website into your theme footer (or a header and footer code plugin), and use a Custom HTML block for the form.
The same CETECommand plugin, with a WooCommerce section for your shop.
Plugins›Add New Plugin›Upload Plugin, choose cetecommand.zip, Install Now, Activate.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
In WordPress: Settings›CETECommand. Paste your booking key into Booking key and press Save Changes.
On the same page, the WooCommerce section shows when WooCommerce is active. Everything in it is off until you tick it. Choose what you want, then Save Changes:
In CETECommand: Invoicing›Settings›Shop orders. Press Turn on shop orders and copy the address (it is shown once).
In WordPress, under WooCommerce orders into CETECommand on the same plugin page, paste it into Shop orders address and press Connect. The plugin adds the WooCommerce webhooks for you (Order created and Order updated) and sends a test. Each order then becomes an invoice in Invoicing, and paid orders are marked paid.
Keep the address secret: anyone with it can make invoices. Shop orders are on paid plans and in your free months.
The shortcodes from the WordPress steps work here too: [cete_enquiry_form], [cete_chat_button] and [cete_client_login]. On a product page you can also place the quote button and questions link yourself:
[cete_quote_button label="Ask for a quote"]
[cete_product_question label="Questions about this product?"]No plugin? Make the webhook yourself: WooCommerce›Settings›Advanced›Webhooks›Add webhook. Status Active, Topic Order created, the shop orders address as the Delivery URL. Add a second one for Order updated to catch payments later. Use the plugin or your own webhooks, not both, so each order comes in once.
Paste the script into your theme once, then add the form with a Custom Liquid section.
In CETECommand: Jobs›Settings›Booking page. Under Your websites add your own domain and your your-shop.myshopify.com address. Save.
In Shopify admin: Online Store›Themes. Next to your current theme press the ... button, then Edit code.
Open layout/theme.liquid. Find </body> near the bottom and paste this just above it. Save.
<script src="https://app.cetechat.com/w/v1.js" data-key="YOUR_BOOKING_KEY" data-chat async></script>Leave out data-chat if you do not want the chat button.
Back in Online Store›Themes, press Customize. Open your Contact page, then Add section, Custom Liquid. Paste this and save.
<div data-cete="enquiry-form"></div>Only quotes: add data-type="quote". Only maintenance requests: data-type="work_order". Leave it out and customers choose (when maintenance requests are on).
Optional. Online Store›Navigation›Main menu, Add menu item. Name it Client login and use this link:
https://app.cetechat.com/p/YOUR_BOOKING_KEYThe form shows on your live shop. The theme editor preview runs on a Shopify address, so it may show a blank space there.
Add the form with Embed a Site, and the chat with Custom code.
In CETECommand: Jobs›Settings›Booking page. Under Your websites add your Wix address (for example yourname.wixsite.com) and your own domain if you have one connected. Save. The form and chat only show on the websites you list.
In the Wix Editor: Add Elements (+), Embed Code, Embed a Site. Paste this address and press Apply:
https://app.cetechat.com/e/YOUR_BOOKING_KEY/embedDrag the box tall enough for the form, about 900 pixels (more with photos). Wix keeps embeds at a fixed height.
For maintenance requests only, add ?type=work_order to the end. For quotes only, ?type=quote. Use Embed a Site, not Embed HTML: Wix runs pasted HTML from a different address, so the form would not show.
In your Wix dashboard: Settings›Custom code (under Advanced). Press + Add Custom Code and paste this. Choose All pages, Load code once, place it in Body - end, then Apply.
<script src="https://app.cetechat.com/w/v1.js" data-key="YOUR_BOOKING_KEY" data-chat async></script>Custom code needs a Wix Premium plan with your own domain connected. Make sure that domain is under Your websites.
Optional. Add a Button, then Link, Web address, and paste:
https://app.cetechat.com/p/YOUR_BOOKING_KEYPress Publish. The form and chat show on your published site, not in the Editor or its preview (those run on a Wix address you have not listed).
Add the script with Code Injection, and the form with a Code block.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
In Squarespace: Website›Pages›Custom Code›Code Injection (on older sites: Settings›Advanced›Code Injection). Paste this into Footer and save.
<script src="https://app.cetechat.com/w/v1.js" data-key="YOUR_BOOKING_KEY" data-chat async></script>Code Injection and Code blocks with scripts need a Core plan or higher (Business on older plans).
Edit your Contact page, press Add Block, choose Code and paste this. Turn off Display Source, then save.
<div data-cete="enquiry-form"></div>Only quotes: add data-type="quote". Only maintenance requests: data-type="work_order". Leave it out and customers choose (when maintenance requests are on).
Optional. Another Code block with this, or a button linking to https://app.cetechat.com/p/YOUR_BOOKING_KEY.
<div data-cete="client-login"></div>Add the script in your project settings, and the form with an Embed element.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
Add your webflow.io address too if you want to test on it.
In Webflow: Site settings›Custom code. Paste this into Footer code and save.
<script src="https://app.cetechat.com/w/v1.js" data-key="YOUR_BOOKING_KEY" data-chat async></script>Custom code needs a paid Webflow site plan.
In the Designer, open the Add panel, drag a Code Embed element onto your page, paste this and save.
<div data-cete="enquiry-form"></div>Only quotes: add data-type="quote". Only maintenance requests: data-type="work_order". Leave it out and customers choose (when maintenance requests are on).
Press Publish. Scripts do not run in the Designer, so check the form on your published site.
Two lines: the script once on every page, and a div where the form goes.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
Paste it just before </body>, or in <head>. It loads after the page, so it does not slow it down.
<script src="https://app.cetechat.com/w/v1.js" data-key="YOUR_BOOKING_KEY" data-chat async></script><div data-cete="enquiry-form"></div>Only quotes: add data-type="quote". Only maintenance requests: data-type="work_order". Leave it out and customers choose (when maintenance requests are on).
<div data-cete="enquiry-form" data-service="Roofing" data-title="Get a roof quote"></div>Optional. The chat button sits in the corner by itself. To open it from your own button as well:
<button type="button" id="chat-with-us">Chat with us</button>
<script>
document.getElementById('chat-with-us').addEventListener('click', function () {
if (window.CETE) window.CETE.openChat();
});
</script>
<!-- A "Client login" link to your client portal -->
<div data-cete="client-login" data-label="Client login"></div>Optional, for analytics. The form element fires a cete:submitted event.
<script>
document.addEventListener('cete:submitted', function (e) {
console.log('Enquiry sent:', e.detail.kind);
});
</script>Load the script once, then drop the form div into any component. It finds forms added later by React.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
Add localhost:3000 (or your dev port) while you build.
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en-AU">
<body>
{children}
<Script
src="https://app.cetechat.com/w/v1.js"
data-key="YOUR_BOOKING_KEY"
data-chat=""
strategy="afterInteractive"
/>
</body>
</html>
);
}Vite or Create React App: paste the plain script tag into index.html instead.
export default function Contact() {
return (
<section>
<h1>Get a quote</h1>
<div data-cete="enquiry-form" data-type="quote" data-service="Roofing" />
<div data-cete="client-login" />
</section>
);
}declare global { interface Window { CETE?: { openChat: () => void } } }
export function ChatButton() {
return <button type="button" onClick={() => window.CETE?.openChat()}>Chat with us</button>;
}Want a typed component? See <EnquiryForm /> in the Node.js package.
Load the script once in your app head, then use the form div in any template.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
Add localhost:5173 (or your dev port) while you build.
export default defineNuxtConfig({
app: {
head: {
script: [
{ src: 'https://app.cetechat.com/w/v1.js', 'data-key': 'YOUR_BOOKING_KEY', 'data-chat': '', async: true },
],
},
},
});Plain Vue with Vite: paste the script tag into index.html.
<template>
<section>
<h1>Get a quote</h1>
<div data-cete="enquiry-form" data-type="quote"></div>
<div data-cete="client-login"></div>
</section>
</template>The script watches the page, so forms on pages opened later by the router show too.
Add the script to your layout. For your own forms, send enquiries from the server with the API.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
{{-- before </body> --}}
<script src="https://app.cetechat.com/w/v1.js" data-key="{{ config('services.cete.booking_key') }}" data-chat async></script>
</body>CETE_BOOKING_KEY=YOUR_BOOKING_KEY'cete' => [
'booking_key' => env('CETE_BOOKING_KEY'),
],Plain PHP: paste the script tag into your shared footer file, such as footer.php. With our PHP package (below) in a Laravel app, @cetecommandScript and @cetecommandEnquiryForm do the same from CETECOMMAND_BOOKING_KEY.
<div data-cete="enquiry-form"></div>Only quotes: add data-type="quote". Only maintenance requests: data-type="work_order". Leave it out and customers choose (when maintenance requests are on).
Send its entries to CETECommand from your controller. See PHP and Laravel below.
Express, Fastify or any Node site: the script goes in your page template. Your server can talk to the API too.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
In EJS, Handlebars, Pug or plain HTML, before </body>:
<script src="https://app.cetechat.com/w/v1.js" data-key="YOUR_BOOKING_KEY" data-chat async></script><div data-cete="enquiry-form"></div>Only quotes: add data-type="quote". Only maintenance requests: data-type="work_order". Leave it out and customers choose (when maintenance requests are on).
Use the API from your server. See Node.js below.
Django, Flask or FastAPI: add the script to your base template.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
{# before </body> #}
<script src="https://app.cetechat.com/w/v1.js" data-key="{{ cete_booking_key }}" data-chat async></script>
</body>Pass cete_booking_key from your settings, or paste the key in. It is public, so that is fine.
{% extends "base.html" %}
{% block content %}
<div data-cete="enquiry-form"></div>
{% endblock %}Only quotes: add data-type="quote". Only maintenance requests: data-type="work_order". Leave it out and customers choose (when maintenance requests are on).
A few lines with requests. See Python below.
Joomla, Drupal, GoDaddy, Weebly, Framer, Carrd, Duda and more. If you can paste code, it works.
In CETECommand: Jobs›Settings›Booking page. Add your website address under Your websites and save. The form and chat only show on the websites you list.
Most website builders call it Custom code, Code injection, Header and footer scripts or Tracking code. Paste the script there so it is on every page.
<script src="https://app.cetechat.com/w/v1.js" data-key="YOUR_BOOKING_KEY" data-chat async></script>Leave out data-chat if you do not want the chat button.
Use an HTML, Embed or Code block where you want the form, and paste one of these:
<div data-cete="enquiry-form"></div><div data-cete="enquiry-form" data-type="quote"></div><div data-cete="enquiry-form" data-type="work_order"></div><div data-cete="client-login"></div>Or link a menu item or button straight to https://app.cetechat.com/p/YOUR_BOOKING_KEY.
Some builders run pasted code from an address of their own, so the form does not show. If yours does, or it only takes a web address, embed the form page itself with its "embed a website" element. Your website address must still be under Your websites.
https://app.cetechat.com/e/YOUR_BOOKING_KEY/embedNo website at all? Share your booking page: https://app.cetechat.com/e/YOUR_BOOKING_KEY. Put it on Google, Facebook and your email signature.
Send enquiries from your own forms, read jobs, customers, quotes and invoices, and hear about changes with signed webhooks.
Our package wraps the REST API, checks webhook signatures and gives you a React form component. Use it from your server only: API keys are secret.
npm install cetecommandimport { CeteCommand } from 'cetecommand';
const cete = new CeteCommand({ apiKey: process.env.CETE_API_KEY });
const enquiry = await cete.enquiries.create({
name: 'Sam Taylor',
email: '[email protected]',
phone: '0400 000 000',
address: '12 Smith St, Parramatta NSW 2150',
service: 'Bathroom renovation',
message: 'Shower is leaking, needs regrouting.',
});
console.log('Enquiry', enquiry.id);const { data: jobs, hasMore, nextBefore } = await cete.jobs.list({ limit: 25 });
for (const job of jobs) {
console.log(job.number, job.title, job.status);
}
// Next page: cete.jobs.list({ before: nextBefore })
// Or every open job, page by page:
for await (const job of cete.jobs.iterate({ status: 'open' })) {
console.log(job.number, job.title);
}import express from 'express';
import { verifyWebhook } from 'cetecommand';
const app = express();
// Before app.use(express.json()): the signature is checked on the raw body.
app.post('/cete/webhook', express.raw({ type: 'application/json' }), (req, res) => {
let event;
try {
event = verifyWebhook({
payload: req.body,
headers: req.headers,
secret: process.env.CETE_WEBHOOK_SECRET,
});
} catch (err) {
return res.status(400).json({ error: err.message });
}
if (event.type === 'enquiry.created') {
console.log('New enquiry from', event.data.name);
}
res.sendStatus(200);
});
app.listen(3000);import { EnquiryForm } from 'cetecommand/react';
export default function Contact() {
return (
<EnquiryForm
bookingKey="YOUR_BOOKING_KEY"
type="quote"
service="Roofing"
onSubmitted={(detail) => console.log('Sent', detail.kind)}
/>
);
}import { sendEnquiry } from 'cetecommand';
// No API key: the booking key is public. Throws CeteCommandError on a problem.
const { message } = await sendEnquiry('YOUR_BOOKING_KEY', {
name: 'Sam Taylor',
email: '[email protected]',
service: 'Bathroom renovation',
message: 'Shower is leaking, needs regrouting.',
});
console.log(message); // your thank you messageThe React component and sendEnquiry use your public booking key, not an API key, so they are safe in the browser (import sendEnquiry from cetecommand/enquiry there). The booking key takes up to 8 enquiries an hour from one address. From your server every enquiry comes from one address, so for a busy form use cete.enquiries.create() with an API key instead.
A small client for the REST API and webhook signatures. Works on any site with PHP 7.4 or later, with or without Composer, and has Laravel support built in (Laravel 8 or later).
composer require cetecommand/cetecommand<?php
require 'vendor/autoload.php';
$cete = new \CeteCommand\Client(getenv('CETE_API_KEY'));
$enquiry = $cete->enquiries()->create([
'name' => 'Sam Taylor',
'email' => '[email protected]',
'phone' => '0400 000 000',
'service' => 'Bathroom renovation',
'message' => 'Shower is leaking, needs regrouting.',
]);
echo $enquiry['id'];$jobs = $cete->jobs()->list(['limit' => 25]);
foreach ($jobs['data'] as $job) {
echo $job['number'] . ' ' . $job['title'] . PHP_EOL;
}
// Next page: $cete->jobs()->list(['before' => $jobs['nextBefore']])
// webhook.php
try {
$event = \CeteCommand\Webhook::verify(
file_get_contents('php://input'),
$_SERVER['HTTP_X_CETE_SIGNATURE'] ?? '',
getenv('CETE_WEBHOOK_SECRET')
);
} catch (\CeteCommand\Exception\SignatureException $e) {
http_response_code(400);
exit;
}
// $event['type'], $event['data']use CeteCommand\Enquiry;
// No API key: the booking key is public. Up to 8 an hour from your server.
$answer = Enquiry::send('YOUR_BOOKING_KEY', [
'name' => 'Sam Taylor',
'email' => '[email protected]',
'message' => 'Shower is leaking, needs regrouting.',
]);
echo $answer['message']; // your thank you messageCETECOMMAND_API_KEY=YOUR_API_KEY
CETECOMMAND_BOOKING_KEY=YOUR_BOOKING_KEY
CETECOMMAND_WEBHOOK_SECRET=YOUR_WEBHOOK_SECRET
CETECOMMAND_CHAT=true// app/Http/Controllers/ContactController.php
use CeteCommand\Client;
use Illuminate\Http\Request;
public function store(Request $request, Client $cete)
{
$data = $request->validate([
'name' => 'required|max:120',
'email' => 'required|email',
'phone' => 'nullable|max:40',
'message' => 'required|max:5000',
]);
// The client comes set up from CETECOMMAND_API_KEY
$cete->enquiries()->create($data + [
'site' => $request->getHost(),
'ip' => $request->ip(),
]);
return back()->with('status', 'Thanks, we will be in touch soon.');
}// routes/api.php (no CSRF check here)
use Illuminate\Http\Request;
Route::post('/cete/webhook', function (Request $request) {
// Checked against CETECOMMAND_WEBHOOK_SECRET by the middleware (400 if not)
$event = $request->attributes->get('cetecommand_event');
// $event['type'] is enquiry.created, job.created, invoice.paid ...
return response()->noContent();
})->middleware('cetecommand.webhook');{{-- In your layout, once (the chat button too, with CETECOMMAND_CHAT=true) --}}
@cetecommandScript
{{-- Where the form goes --}}
@cetecommandEnquiryForm(['type' => 'quote', 'service' => 'Roofing'])
{{-- A client portal link --}}
@cetecommandClientLogin(['label' => 'Client login'])Shared hosting without Composer? Upload cetecommand.php and the src folder side by side and require cetecommand.php instead of vendor/autoload.php.
No package yet: requests and the standard library do the job.
import requests
r = requests.post(
"https://app.cetechat.com/e/YOUR_BOOKING_KEY/api",
json={
"name": "Sam Taylor",
"email": "[email protected]",
"phone": "0400 000 000",
"address": "12 Smith St, Parramatta NSW 2150",
"service": "Bathroom renovation",
"message": "Shower is leaking, needs regrouting.",
"preferred": "Weekday mornings",
},
timeout=10,
)
r.raise_for_status()
print(r.json()["message"]) # your thank you messagerequests.post(
"https://app.cetechat.com/e/YOUR_BOOKING_KEY/api",
json={
"kind": "work_order",
"name": "Priya Shah",
"email": "[email protected]",
"company": "Harbour Strata",
"orderNumber": "PO-4471",
"address": "8/22 Bay Rd, Wollongong NSW 2500",
"lot": "8",
"strataPlan": "SP12345",
"tenantName": "Tom",
"tenantPhone": "0400 111 222",
"access": "Key in the lockbox, code 1234",
"urgency": "urgent", # routine, soon, urgent or emergency
"message": "Hot water system leaking.",
},
timeout=10,
).raise_for_status()import hashlib, hmac, os, time
from flask import Flask, abort, request
app = Flask(__name__)
SECRET = os.environ["CETE_WEBHOOK_SECRET"] # YOUR_WEBHOOK_SECRET
def verify(raw: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
t, sig = parts.get("t", ""), parts.get("v1", "")
if not t.isdigit() or abs(time.time() - int(t)) > 300:
return False
want = hmac.new(secret.encode(), t.encode() + b"." + raw, hashlib.sha256).hexdigest()
return hmac.compare_digest(want, sig)
@app.post("/cete/webhook")
def cete_webhook():
if not verify(request.get_data(), request.headers.get("X-Cete-Signature", ""), SECRET):
abort(400)
event = request.get_json()
if event["type"] == "enquiry.created":
print("New enquiry from", event["data"]["name"])
return "", 200import os, requests
r = requests.get(
"https://app.cetechat.com/v1/jobs",
headers={"Authorization": f"Bearer {os.environ['CETE_API_KEY']}"},
params={"limit": 25},
timeout=10,
)
r.raise_for_status()
for job in r.json()["data"]:
print(job["number"], job["title"], job["status"])The booking key address needs no secret, and from a browser it only takes enquiries from your listed websites. It takes up to 8 enquiries an hour from one address, though, and from your server every enquiry comes from one address. For a busy form, send them with an API key instead: POST https://app.cetechat.com/v1/enquiries with the same fields.
Make a key in CETECommand: Jobs›Settings›API and webhooks. Send it as a Bearer token from your server. 120 requests a minute per key. Lists take ?limit= (up to 100) and ?before= to page back.
curl https://app.cetechat.com/v1/ping \
-H "Authorization: Bearer YOUR_API_KEY"| Method | Path | What it does |
|---|---|---|
GET | /v1/ping | Check your key |
GET POST | /v1/enquiries | List or add enquiries |
GET | /v1/enquiries/:id | One enquiry |
GET POST | /v1/customers | List (by email or search) or add customers |
GET | /v1/customers/:id | One customer |
GET | /v1/jobs | List jobs |
GET | /v1/jobs/:id | One job |
GET | /v1/documents | List quotes and invoices |
GET | /v1/documents/:id | One quote or invoice, with its link |
Add an HTTPS address in the same place and pick events. Each one is a signed JSON POST: X-Cete-Event, X-Cete-Delivery and X-Cete-Signature: t=<time>,v1=<HMAC-SHA256 of "t.body">. Answer with a 2xx within 8 seconds.
| Event | When |
|---|---|
enquiry.created | A new enquiry (website form, booking page, email, chat or API) |
webchat.created | A visitor started a website chat |
job.created | A job was made |
job.status_changed | A job moved to another status |
quote.accepted | A customer accepted a quote or work order |
quote.declined | A customer declined a quote or work order |
invoice.paid | An invoice was paid in full |
Each one comes with a note in your team chat, so the right person sees it straight away.
One tap turns it into a customer and a job, with the photos and access notes already on it.
Answer from your phone or the office. Turn a chat into an enquiry when they want a quote.
Each order becomes an invoice. Paid orders are marked paid, and customers are matched by email.
Yes. The enquiry form, website chat and client portal work on every plan, including Free. Shop orders into Invoicing are on paid plans and in your free months.
No. It is one small script that loads after your page. The form only loads where you put it, and the chat button only when you turn chat on.
Yes. Your booking key is public on purpose: it is already in your booking page address, and it only lets your listed websites show your form and send you enquiries. API keys are different. They are secret, like a password. Only use them on a server, and never put them in browser code.
Not for most websites. WordPress has a plugin, and Shopify, Wix, Squarespace and Webflow are copy and paste. A developer only helps if you want your own form, a custom design, or to connect other software with the API.
Check your website address is listed under Your websites in Jobs, Settings, Booking page (no need for https or www), and that you saved. Website builders often skip scripts in their editor preview, so check your published site.
Yes. Send them a link to this page and the code from Website code. They do not need a login to CETECommand.
Launch offer: the first 100 businesses get 3 months of everything free, no card. Set up your website form today.
Questions? Talk to us.