How to run a business site on Stave: every screen in the business admin, the tools Stave staff use, each connected service and the API the client sites and partners call.
Admin admin.stave.worksWritten October 26, 2026Screens shown Golden Road Vineyards, with people's names and contact details swapped for made-up ones
Getting in
Everyone signs in at admin.stave.works. There is no public sign-up. A Stave admin adds a business and its first owner, and owners invite the rest of their team.
Sign in with a password, or ask for a link by email.Forgot your password sends a reset link.
Signing in
Password. Enter your email and password and press Sign in.
Email link. Press Email me a link instead. Stave emails a one-time sign-in link to addresses that already have an account. Unknown addresses get nothing.
Forgot your password. Enter your email and Stave sends a reset link that works for one hour. This also works for someone who has never set a password, for example an owner who came across from Stave 1.0.
Invitations. An invite email opens /invite/<token>. Someone new enters their name and Stave emails them a sign-in link. Someone with an account already signs in and accepts. Either can add a password later with Forgot your password.
Who can do what
Role
Can do
Owner
Everything for their business, including business info, connected services, the team, site health and text messages.
Member
Pages, posts, wines, beers, events, photos and the day-to-day lists. Members can't change business info, connected services or the team.
Stave admin
Every business, plus the staff area at /stave. Admins must set up two-factor sign-in before they can do anything, and they can view the admin as any person (see View as).
After signing in, people land on their business at /b/<slug>, for example /b/grv. Someone who belongs to more than one switches with the business name at the top of the sidebar.
The business admin
The sidebar only shows what a business uses. A Stave admin switches sections (Blog, Wines, Events and so on) and plugins on per business, and screens for anything switched off disappear. Screens marked Owner are hidden from members.
Sidebar group
Screens
Shown when
Top
Home, Messages
Always
Site
Pages, Site settings, Redirects, Board
Always
Review notes
Review notes plugin
Site health Owner
Site health plugin
Content
Posts
Blog section
Wines · Beers
Wines section · Beers section
Events, Ticket sales
Events section
Shop
Shop section
Media
Always
Customers
Contacts
Always
Wine club
Club section
Reservations
Visit or Tasting room section
Text messages Owner
Text messages plugin
Stay
Units, Bookings
Stay section
Guides
Stay section and Stay guide plugin
Business
Business info, Connected services, Team Owner
Always, owners only
Home
/b/grv
The first screen after signing in. It shows when the site was last published and how many pages have changes waiting, shortcuts to write a post, add an event, add a wine or upload photos, a Needs your attention list (unpublished pages, new club requests, open review notes, connectors that stopped working), what's coming up and recent activity.
Home. Each item under Needs your attention links straight to the fix.
The whole admin works on a phone. The sidebar folds into the menu button at the top left.
Home at phone width.
Messages
/b/grv/messages
Everything sent through forms on the site. Stave also emails each message to the business. Form settings sets which address gets new messages and what the automatic reply to the sender says.
Messages with nothing waiting.
Pages
/b/grv/pages
Every page on the site with its address, when it was last edited and whether it has unpublished changes. Click a page to edit it. Use New page to add one, and the ⋯ menu on a row to duplicate or delete one.
Pages. Unpublished changes means visitors still see the old version.
Editing a page
/b/grv/pages/<id>
The left column lists the sections on the page (hero, hours, featured products and so on). Drag to reorder, or use Add section. The site header and footer are shared by every page and edited under Site settings.
Click any section in the preview to edit it. Its text becomes editable where it sits.
The right column holds the page settings: name, web address, the title and description search engines show, and a preview of how the page looks on Google.
Changes save as a draft automatically. Use the desktop, tablet and phone buttons at the top to check sizes, and undo or redo from the same bar.
Press Publish when it's ready. Nothing changes on the live site until then.
The page editor. The live preview loads the client's own site, so in this local copy it shows a placeholder.
Site settings
/b/grv/site
The header menu, footer and other settings shared by every page. Reorder menu items with the arrows, open one to change its label or link, then Save draft or Publish.
Site settings.
Redirects
/b/grv/redirects
Send an old address to its new home, so old links and search results keep working. Add one when a page moves or a new site replaces an old one. Choose permanent (308) for moves that stick and temporary (307) for anything short-lived. Stave applies them on the business's own domains, and client sites hosted elsewhere look them up through the redirects API.
Redirects.
Review notes
/b/grv/notes
Comments pinned to a spot on a page, shared between the business and Stave while a site is being reviewed. Open the site while signed in and use the Review button to drop a note on any element. Notes have a kind (design, copy, bug, question, idea), a priority and a status (open, in progress, resolved). Visitors never see the button or the pins.
Review notes, filtered by status.
Site health Owner
/b/grv/health
Scores for how the site does with AI assistants, search engines and speed, each with the findings behind it: what needs a fix and what's already working. A Stave admin sets how often the checks run.
Site health.
Board
/b/grv/board · TV address /t/grv/board
The menu for the TV in the tasting room. Open the TV address in the TV's browser and leave it. It updates itself and never needs a login.
What shows: everything that's pouring, or only the drinks you pick.
Tastings and flights: board-only items that aren't wines or beers.
Banner: one line that scrolls across the top. Leave it empty for no banner.
Prices and sizes: select several drinks and give them the same sizes and prices in one step.
Board settings with a live preview of the TV.
Posts, wines and beers
Posts
/b/grv/posts
The blog. Tabs split drafts, scheduled and published posts. Write a post opens the editor.
Posts.
Set a cover photo, a title and the body. The toolbar handles headings, bold, italic, quotes, lists and links, and can drop in a wine, an event or a photo.
The side panel holds the web address, categories, a short summary (160 characters for search results), the byline and a Google preview.
Publish now, or pick a time from the publish menu. Scheduled posts go live at the top of the next hour after their time.
The post editor.
Wines
/b/grv/wines
The wine list. Changes show on the site right away, with no publish step. Prices and stock also feed the shop. Use the arrows to set the order wines appear in, and the status to mark a wine on the menu or sold out. When Vinoshipper is connected, its catalog sync keeps wines in step.
Wines.
Beers
/b/grv/beers
Guest beers poured in the tasting room, grouped by style. They show on the TV board and the tasting room menu and aren't sold online. The toggle on each row puts it on or takes it off the board. Breweries using Untappd can sync their menu instead of typing it.
Beers.
Events and ticket sales
Events
/b/grv/events
Upcoming and past events. With Facebook Events connected, events from the Facebook Page come in every 8 hours, including changes and cancellations. Check Facebook now pulls them immediately. Add an event creates one by hand.
Events. From Facebook marks imported ones.
Ticket sales
/b/grv/tickets
Tickets sold, ticket money, events on sale and orders waiting for payment, then every upcoming event with its sales. Paid tickets need Stripe or Square connected. Without one, guests can only get free tickets.
Ticket sales. The banner offers to connect Stripe.
Press Set up tickets on an event.
Add a ticket type with a name, a price (zero for free RSVPs), a description and how many are available.
The Sales card shows whether guests can buy. Turn sales off stops new orders without hiding the event.
The Guests tab lists ticket holders, and Orders lists orders with refunds.
On the night, staff open /scan on a phone, signed in, and scan each ticket's QR code to check guests in.
One event's tickets.
Guests buy on /t/grv/tickets/<event> and get an order page, a ticket page per ticket with a QR code, and an Apple Wallet pass when Wallet is configured.
Shop and media
Shop
/b/grv/shop
What the site's shop sells and where orders go. For a winery on Vinoshipper, guests pick wines on the Shop page and check out in Vinoshipper's cart. Vinoshipper takes the payment, checks age and ships, and Stave doesn't get a copy of those orders. Sync now pulls the catalog. Event tickets are separate and live under Ticket sales.
Shop.
Media
/b/grv/media
Upload once and use anywhere on the site. Drop JPG, PNG or WebP files up to 4.5 MB on the page or press Upload. Stave resizes them for fast loading. Filter by photos or bottles, and use Needs a description to find images missing alt text.
Media.
Contacts and wine club
Contacts
/b/grv/contacts
Everyone who signs up on the site lands here, and Add contact adds someone by hand. Search by name, email or phone and filter by where they signed up or email status. The Texts column shows who opted in to text messages. Text opt-in needs a phone number and a date of birth showing the person is 21 or older.
Contacts.
Wine club
/b/grv/club
Three tabs: Requests from people asking for a place on the list, Members and Tiers. Changing a request's status (new, invited, declined) sends nothing, so write to the person yourself. Members join a tier through the site and get a private page at /club/manage/<token> to pause, skip a shipment, switch between pickup and shipping, update their address or cancel.
Tasting room and visit reservations made from the site, with party size and notes.
Reservations.
Open Reservation settings to take bookings:
Take reservations on your site turns the booking page on. When it's off, the page tells people reservations aren't open.
Confirm right away confirms and emails the guest while the time has room. Turn it off to review each one as a request.
Largest party the form accepts. Bigger groups are told to get in touch.
Days and times sets which slots can be booked and how many seats each holds. Nobody can reserve until at least one exists.
Reservation settings.
Guests get a confirmation email with a link to add the visit to their calendar, and a reminder email on the morning of the visit.
Text messages Owner
/b/grv/sms
Marketing texts sent from the business's own Telnyx account and number, only to people who opted in. A Stave admin turns on the Text messages plugin first. That adds this screen and unlocks the Telnyx connector.
Before Telnyx is connected, the screen points to Connected services.
Press New text. Give it a name, write the message and check the preview.
Under Who gets it, pick contact tags or everyone. Only people who opted in are counted.
Leave Schedule empty to send now, or pick a time. Press Schedule, or Save draft to finish later.
Stave sends due texts every five minutes and keeps per-campaign delivery counts. STOP and HELP replies are handled for you.
With the plugin off, saving the Telnyx connector and sending campaigns are both refused, but STOP and HELP replies are still honored.
Stays and guest guides
Units
/b/grv/units
The places guests can book, with photos, sleeping details, rates and rules for the stay page. Each unit has a booking link. If it's set, the site's Book button sends guests there (Airbnb, VRBO). Clear it and guests use Stave's own request form.
Units.
Bookings
/b/grv/bookings
A month calendar per unit showing stays booked through Stave, requests that need a reply and stays pulled in from outside calendars. Stave reads each unit's Airbnb or VRBO calendar every two hours, and publishes its own feed at /api/stays/ical/<token> so those sites can block the same dates. Add booking enters one by hand.
Bookings.
Guides
/b/grv/guides
What guests read once they've booked: door code, wifi, house manual and local favorites. Each guide has a private link (/g/<token>) that never changes, so a printed QR code keeps working. Only people with the link can see it.
Guides.
Business info and team
Business info Owner
/b/grv/business
Hours, address, phone, email and social links. These show on every page of the site, in the business's Google listing data and in what AI assistants say about it. Hours lines can be days, date ranges or words like "By appointment". Press Save when done.
Business info.
Team Owner
/b/grv/team
People who can sign in to this business. Invite someone emails an invite as owner or member. Pending invites can be resent or revoked, and existing people can be changed between roles or removed. A business always keeps at least one owner.
Team.
Connected services Owner
/b/grv/connectors
Link the outside services a business already uses. Only owners and Stave staff can open this screen. Keys and tokens are stored encrypted and can never be read back. Leaving a key field empty keeps the saved one.
Connected services, grouped by what each one does.
Services fall into three groups:
Pulls your information in: Facebook Events, Untappd, Vinoshipper, Telnyx and Square. Each has a sync that runs on a schedule and a button to run it now.
Works on your site: Stripe and Google Analytics, used directly by pages and checkout.
Saves your keys only: Google Business Profile, Mailchimp, Commerce7, WineDirect, Toast, Arryved and Ollie. You can save keys and mark these on, but Stave doesn't talk to them yet.
Setting up any service
Press Set up on the service. A panel opens on the right.
Fill in the fields. Each one says where to find the value in the other service.
Tick the capabilities you want, where the service has them.
Turn it On and press Save.
Press Check credentials to test the keys, then Sync now for services that sync. The row shows when it last synced and why, if it failed.
Turning a service off stops it syncing and being used, but keeps the saved details. Disconnect deletes them.
Vinoshipper's panel.Stripe's panel.
Setting up Telnyx
Telnyx sends the business's marketing texts from its own account, so Stave never pays for or owns the number.
Stave turns on Text messages. A Stave admin opens the business under Businesses, Sections and plugins, and switches on the Text messages plugin. Telnyx then appears under Connected services.
API key. Telnyx portal, Account, API keys. Paste it into API key.
Messaging profile. Telnyx portal, Messaging, Messaging profiles. Copy the ID of the profile the number belongs to.
Send from. With the key saved, press Load list and pick the number, or type it as +1XXXXXXXXXX.
Webhook public key. Telnyx portal, Account, Keys and credentials, Public key. Without it Stave refuses STOP replies, because anyone who found the webhook address could otherwise opt contacts in and out.
10DLC campaign ID. The registered campaign the number sends under. US carriers quietly filter unregistered marketing texts, so a send can look successful and never arrive. Registration happens in Telnyx.
Webhook address. In the Telnyx messaging profile, set the inbound webhook to https://admin.stave.works/api/connectors/telnyx/webhook/<business id>. Golden Road's business id is 4.
Tick Marketing campaigns, turn it On, Save, then press Check connection. It warns about a missing 10DLC campaign ID, a number that isn't active or a missing messaging profile.
Telnyx's panel.
Outside production, Stave only texts numbers listed in SMS_ALLOWLIST, so tests on staging can't reach real customers.
Every service
Facebook Events Syncs every 8 hours
Upcoming events on the business's Facebook Page import automatically and stay in step, cancellations included. Press Connect with Facebook and approve access. Stave stores the Page token.
Field
Where to find it
Page ID
Filled in when you connect. If the Facebook account manages several Pages, set the ID of the one to import from.
Untappd Syncs every 8 hours
Menus sync into Wines, Beers, Ciders and Meads and stay up to date.
Field
Where to find it
Account email
The Untappd for Business login the API token belongs to.
API token sealed
Untappd for Business, Account settings, API access. A read-only token works.
Menu ID
Optional. Sync only this menu. Leave empty to sync every menu on the account.
Vinoshipper Syncs every 8 hours
Compliant wine shipping. The Account ID powers the Vinoshipper block on pages, and an API key adds the catalog sync.
Field
Where to find it
Account ID
Vinoshipper, Account, Integrations, Vinoshipper Injector. It's the number in the init() line of the snippet. This alone powers the page block.
Tasting menu catalog ID
Optional. Vinoshipper, Products, Catalogs. Wines in this catalog are marked as poured in the tasting room.
API key, API secret sealed
Optional. Only some Vinoshipper plans offer them.
Capabilities: Product catalog (copies the wine list into products every 8 hours). Inventory, orders, customers, clubs and shipping compliance checks are listed as coming later.
Telnyx Check on demandNeeds Text messages plugin
Marketing texts from the business's own Telnyx account and number. Powers campaigns under Text messages and passes STOP and HELP replies back to the contact. Setup steps are above.
Field
Where to find it
API key sealed
Telnyx portal, Account, API keys.
Messaging profile
Telnyx portal, Messaging, Messaging profiles.
Send from
A number on the account. Load the list or type +1XXXXXXXXXX.
Webhook public key
Telnyx portal, Account, Keys and credentials, Public key.
10DLC campaign ID
The registered campaign the number sends under.
Capabilities: Marketing campaigns. Order and booking texts are listed as coming later.
Square Syncs every 8 hours
Point of sale, payments and stock. Takes ticket payments and keeps product availability matched to the register. Products are matched to Square items by name on the first sync.
Field
Where to find it
Access token sealed
Square Developer dashboard, the app's credentials.
Application ID
Same page. An ID starting sandbox- uses Square's test mode.
Location ID
The location whose stock counts drive availability on the site.
Capabilities: Card payments and Catalog and stock sync (reads from Square only). Outside production Stave refuses a production Square application.
Stripe Works on your site
Card payments for tickets and orders, paid straight into the business's own Stripe account. The usual route is the Connect Stripe button on Ticket sales, which runs Stripe's own onboarding and fills in the account ID.
Field
Where to find it
Secret key sealed
Stripe dashboard, Developers, API keys. A test key uses Stripe's test mode for a fake payment end to end.
Publishable key
Same page. Must pair with the secret key.
Connected account ID
Filled in by Stripe onboarding. Only paste one when moving an account across from elsewhere.
Google Analytics Works on your site
Page views, traffic sources and conversions in the business's own Google Analytics property. The ID is passed to the client site through the site content API.
Field
Where to find it
Measurement ID
Google Analytics, Admin, Data streams, the web stream for the site. It starts with G-.
Saves keys only Not used yet
These store credentials so they're ready when Stave starts using them. Nothing syncs.
Service
For
Fields
Google Business Profile
Hours, reviews and map
Place ID
Mailchimp
Email and newsletter marketing
API key, Audience ID
Commerce7
Winery sales and customer records
Tenant ID, App ID, Secret key
WineDirect
Winery online store and fulfillment
API key
Toast
Restaurant and taproom point of sale
Client ID, Client secret
Arryved
Brewery and taproom point of sale
API key
Ollie
Brewery management and production
API key
Pages guests use
The client's own website (grvwines.com for Golden Road) shows the content. A few guest pages are served by Stave itself, and the client site links to them.
Address
What it is
/t/<slug>/reservations
Book a tasting or visit.
/t/<slug>/tickets/<event>
Buy tickets for one event.
/t/<slug>/stay/book
Request a stay.
/t/<slug>/board
The tasting room TV menu.
/order/<number>
An order and its tickets.
/ticket/<code>
One ticket with its QR code and Wallet pass.
/club/manage/<token>
A club member's own page.
/g/<token>
A guest guide.
stave.works/reports/<slug>
A published audit report, behind its access code. Add /present for the slideshow.
/scan
Staff ticket check-in. Needs a signed-in team member.
Buying tickets.Requesting a stay.
The reservations page while reservations are switched off.
Stave staff tools
Stave admins get a second sidebar at /stave: Overview, Businesses, Users, Change log, Audits and Leads. Two-factor sign-in is required before any of it opens.
Overview: live and paused sites, audits waiting, new leads and users.
Businesses
/stave/businesses
Every business with its domain, theme, sections and status. Open as owner jumps into its admin. Add a business asks for a name, slug, domain and theme.
Businesses.
Opening a business shows six tabs:
Tab
What it's for
Sections and plugins
Which screens the business sees and which pages its site has. Changes apply as soon as you flip them.
Domains
The domains the business owns. Redirects and domain lookups use these.
People
Owners and members, pending invites, and View as for each person. Owners can invite and remove their own people, so staff only step in when nobody at the business can sign in.
Settings
Business name, site status, the Vercel project ID and how often AI audits run (off, weekly, fortnightly, monthly or quarterly).
AI runs
Audit runs for this business: queued, running, done, failed or cancelled.
Theme
Minimal, Contour or Golden Road.
Sections.Plugins, including Text messages.People.Settings.
Plugin
Adds
Review notes
Pinned page notes while a site is being reviewed.
Site health
Speed and AI visibility reports for the owner.
Stay guide
Guest guides for stays.
Text messages
The Text messages screen and the Telnyx connector.
Users and View as
/stave/users
Everyone who can sign in, the businesses they belong to, their Stave role, whether two-factor is on and when they last signed in.
Users.
View as opens the admin exactly as that person sees it, with their role and sidebar, so you can reproduce a problem they report. A banner stays at the top while you're viewing. Stop viewing returns you to your own account.
Viewing as an owner. The banner names who and where.
Every change made while viewing as someone is recorded in the Change log (/stave/log) with who did it, who they were viewing as, the business, the change and a diff.
Change log.
Audits and leads
/stave/audits · /stave/leads
Audits lists AI visibility and site speed reports. Run an audit starts one for a business. Nothing goes to the business until you publish it. Published reports are served at stave.works/reports/<slug> behind an access code. Reports produced on another machine are uploaded through the audit import API.
Leads come from the free audit and the contact form on stave.works. Set each one's stage as it moves along.
Audits.Leads.
API
All endpoints live on the admin host, https://admin.stave.works/api/…. Requests and responses are JSON unless noted. Errors come back as { "ok": false, "error": "…" } with a matching status.
How calls sign in
Kind
How
Used by
Public
No credentials. Form endpoints have per-IP rate limits and a bot check.
Guest pages and client sites
Signed link
A token or signature in the URL is the credential.
Tickets, iCal feeds, club pages
Session
The signed-in admin cookie, plus the business slug as tenant. Many need the owner role.
For bearer endpoints, a wrong secret returns 401 and an unset one returns 404, so a missing environment variable doesn't look like a working endpoint.
Public forms use two bot fields. hp is a hidden honeypot that must stay empty. t is the time the form was shown, in milliseconds since the epoch, and a submit under 2.5 seconds later is treated as a bot. A caught request gets a fake success so bots learn nothing.
Site content
GET /api/site-content?tenant=<slug>[&draft=1]
The client site's whole content in one call: business details, site settings, pages, products, events, posts, categories and units. The client site fetches this server side and renders it in its own design.
Auth
Bearer SITE_CONTENT_SECRET (32 characters or more). The secret is shared by all businesses, and tenant picks one.
Query
tenant (required) and draft=1 for unpublished content, used by the client's preview route. There are no per-collection filters.
Limit
20 requests a minute per caller, checked before auth. A full crawl of a client site in development can trip it.
Returns
ok, version, draft, generatedAt, tenant, vinoshipperAccountId, googleAnalyticsId, site, pages, products, events, posts, postCategories, units, blockRelations, plus media (newest 1,000) when draft=1. Sent with no-store and noindex.
Errors
400 no tenant, 401 wrong secret, 404 unknown or inactive business, 429 over the limit.
A client site needs STAVE_CONTENT_URL, STAVE_CONTENT_SECRET, STAVE_TENANT_SLUG, STAVE_ADMIN_ORIGIN and NEXT_PUBLIC_MEDIA_ORIGIN.
GET /api/media/file/{path…}
Serves uploaded images and files. Public.
GET /api/redirects?host=&path=
The same redirect lookup Stave runs on every request, for callers that ask over HTTP. Public, cached for 60 seconds. Returns { found: true, to, permanent } or { found: false, hasRedirects }.
GET /api/health
Returns { ok: true }.
Forms and sign-ups
POST /api/forms/submit
Submits a form built in the admin. Saves it to Messages, emails the business and sends an auto-reply when a field held an email address. Public, 10 per 10 minutes per IP. t is required here.
Body
formId (number), values (object keyed f0, f1… by field position), t, hp
Returns
{ ok: true, message }, the form's thank-you text
POST /api/intake/newsletter POST /api/intake/club-request
Newsletter and club list sign-ups from a client site's own forms. Called server side with the site secret. Rate limited to 5 per 10 minutes per business and email.
Auth
Bearer SITE_CONTENT_SECRET
Body
tenant, email (required), name (required for club requests), phone, smsConsent (needs phone and dob as YYYY-MM-DD, 21 or older), sourceDetail, smsConsentSource, smsConsentIp, note (club requests, up to 1,000 characters), hp, t
Returns
{ ok: true }. The contact is created or updated, and a club request is stored as well.
POST /api/club/join
Joins a club tier. Public, 5 per 10 minutes per IP.
Body
tierId, name, email (required), tenant, phone, fulfillment (pickup or ship), shipping {line1, line2, city, state, postalCode}, notes
Returns
{ ok: true, portalUrl } for a new member, or { ok: true, alreadyMember: true } with the link emailed instead
POST /api/club/manage
A member's own changes. The portal token in the body is the credential.
Stripe events. The address is saved in Stripe, so it must not move.
Confirm endpoints allow 30 calls per 10 minutes per IP and 10 per order.
Connectors
All of these except the webhooks and the Facebook callback need an owner's session, with the business slug as tenant in the body (or the query for GET).
Method
Path
What it does
GET
/api/connectors/facebook/oauth?tenant=
Sends the owner to Facebook to approve access.
GET
/api/connectors/facebook/callback
Facebook sends the owner back here. Saves the Page token and returns to Connected services.
Tests saved credentials. Returns a location, a location count, a product count or a number count.
POST
/api/connectors/telnyx/numbers
Lists the account's numbers for the Send from picker. Optional config.apiKey tests a key before saving.
POST
/api/connectors/telnyx/webhook/{businessId}
Inbound texts from Telnyx, verified with the saved webhook public key. Handles STOP and HELP.
GET
/api/sms/audience?tenant=&tags=
How many opted-in contacts a campaign would reach.
POST
/api/sms/send-due
Body tenant, campaignId. Sends one campaign now. GET on the same path is the cron.
Admin and machine
Method
Path
Auth
What it does
POST
/api/media/upload
Session
Multipart tenant, file, alt. Up to 4.5 MB.
GETPOST
/api/annotate
Session
List or add review notes for a page. Business from ?tenant=. Body path, note, kind, priority, pageTitle, anchor, viewport.
PATCHDELETE
/api/annotate/{id}
Session
Change a note's status, kind, priority, note or add a reply, or delete it.
POST
/api/monitoring/run
Stave admin
Body tenant (numeric id). Starts an audit run and returns runId.
GET
/api/monitoring/runs/{id}
Stave admin
One run's status, modules, recent events and scores.
GET
/api/monitoring/due
Maintenance secret
Businesses with an audit run requested, for the runner.
POST
/api/audits/import
Audit import token
Uploads a finished audit report bundle. Body bundle (or the older flat fields), tenantSlug, slug, accessCode, replace. Returns { slug, accessCode, url }.
GETPOST
/api/auth/{path…}
varies
Sign-in, sign-out, password reset, email links and two-factor, handled by better-auth.
Scheduled jobs
Vercel cron calls these with CRON_SECRET. Times are UTC.
Path
Schedule
What it does
/api/sms/send-due
Every 5 minutes
Sends text campaigns whose time has come.
/api/cron/publish-scheduled
Hourly, on the hour
Publishes scheduled posts.
/api/stays/sync-ical
Every 2 hours
Reads Airbnb and VRBO calendars into Bookings.
/api/connectors/facebook/sync
Every 8 hours
Imports Facebook events.
/api/connectors/vinoshipper/sync
Every 8 hours
Syncs Vinoshipper catalogs.
/api/connectors/untappd/sync
Every 8 hours
Syncs Untappd menus.
/api/connectors/square/sync
Every 8 hours
Syncs Square stock.
/api/reservations/remind
Daily, 13:00
Emails reminders for the day's confirmed reservations (9 am Eastern in summer, 8 am in winter).
Each sync covers every active business with that connector turned on, and records the result on the connector's row in Connected services.
Running Stave
Production
Staging
Address
admin.stave.works
stave-git-stage-onenomad.vercel.app
Branch
main
stage
Vercel project
stave
stave, preview for the stage branch
STAVE_ENV
production
staging
Email
Sends normally
Only to addresses in EMAIL_ALLOWLIST
Texts
Sends normally
Only to numbers in SMS_ALLOWLIST
Payments
Live keys
Stripe and Square test keys only. Live keys are refused.
Code flows development → stage → main through pull requests on OneNomad-LLC/stave-cms-2. Every other branch is skipped by Vercel. Database migrations run as part of each build.
Environment variables
Names only. Values live in Vercel and the password vault.
Variable
For
DATABASE_URL, DATABASE_URL_UNPOOLED
Postgres (Neon)
BETTER_AUTH_SECRET, BETTER_AUTH_URL
Sign-in sessions and the admin's own address
CONNECTOR_SECRET_KEY
Encrypts saved connector keys. Changing it makes every saved key unreadable, and owners have to enter them again.