Introduction

Enquiry

Hono Worker that accepts enquiry POSTs from marketing sites, stores submissions in D1, persists attachments in R2, and optionally sends team email when ENQUIRY_EMAIL_ENABLED=true.

Sites POST from the browser to https://api.mayawealth.co.uk/enquiry/v1/enquiries (via gateway). Staff and integrators read stored submissions through the gateway using either a Directory JWT or a per-site service API key.

Three access patterns

Browser forms — POST /v1/enquiries is origin-checked and uses Turnstile (unless forwarded by a trusted site Worker or the gateway). Staff inbox — GET /v1/enquiries and related routes require a Directory JWT. Integration — GET /v1/integration/organisations/{organisationId}/enquiries requires X-Enquiry-Api-Key, X-Enquiry-Integration-Secret, and an organisationId that matches the key's site. See Integration API below.


What it owns

  • Validating branded enquiry payloads (site, fields, honeypot, turnstileToken)
  • Sending mail from noreply@mayawealth.co.uk when email is enabled
  • Persisting accepted submissions (not honeypots) in D1
  • Optional per-site webhooks: enquiry.created, enquiry.status_changed
  • OpenAPI contract on this documentation site only: Enquiry API reference (not on the live Worker)

What it does not own


Clients

ClientPattern
Marketing sites (Telcam, Maya Wealth, Maya Construction)Browser → gateway → POST /v1/enquiries
Site Workers (car-warranty, telcam-auto, butlr)Browser → same-origin /api/enquiry/v1/enquiries → site Worker → gateway
Car Warranty staff (Workshop app)Integration API key + secret (injected by site Worker)
CRM / automationSame integration API + webhooks

Telcam, Telcam Auto, Maya Wealth, Maya Construction, car-warranty, and Butlr each use a distinct site field in the POST body.

Local health check (via gateway in dev): { "ok": true, "service": "enquiry" }.


Integration API

Use the integration API to list, read, update status, and download attachments for one marketing site. Calls go to the unified gateway; no browser Origin is required.

Base URL: https://api.mayawealth.co.uk/enquiry

Auth (both required):

  • X-Enquiry-Api-Key: enq_live_… (or Authorization: Bearer enq_live_…)
  • X-Enquiry-Integration-Secret: … — Worker env {SITE}_ENQUIRY_INTEGRATION_SECRET

organisationId in the path must match the Directory org for the site tied to the API key.

Legacy paths without organisationId (/v1/integration/enquiries, /v1/public/enquiries) still work but are deprecated.

API keys

SiteWorker secret name
telcamTELCAM_ENQUIRY_API_KEY
telcam-autoTELCAM_AUTO_ENQUIRY_API_KEY
maya-wealthMAYA_WEALTH_ENQUIRY_API_KEY
maya-constructionMAYA_CONSTRUCTION_ENQUIRY_API_KEY
car-warrantyCAR_WARRANTY_ENQUIRY_API_KEY
butlrBUTLR_ENQUIRY_API_KEY

Keys are stored only on the enquiry Worker (wrangler secret put or deploy secrets from apis/enquiry). Do not put them on marketing Pages projects.

Routes

MethodPathPurpose
GET/v1/integration/organisations/{organisationId}/enquiriesList inbox (status, q, page, page_size)
GET/v1/integration/organisations/{organisationId}/enquiries/{id}One submission
GET/v1/integration/organisations/{organisationId}/enquiries/{id}/attachments/{attachmentId}Download file
PATCH/v1/integration/organisations/{organisationId}/enquiries/{id}Update status (new, read, closed)

Telcam example

Bash:

curl -sS \
  -X GET \
  -H "X-Enquiry-Api-Key: $TELCAM_ENQUIRY_API_KEY" \
  -H "X-Enquiry-Integration-Secret: $TELCAM_ENQUIRY_INTEGRATION_SECRET" \
  "https://api.mayawealth.co.uk/enquiry/v1/integration/organisations/$TELCAM_ORG_ID/enquiries?status=new&page_size=25"

Windows cmd (one line; do not prefix the key with $):

curl -sS \
  -X GET \
  -H "X-Enquiry-Api-Key: enq_live_YOUR_KEY_HERE" \
  -H "X-Enquiry-Integration-Secret: YOUR_INTEGRATION_SECRET" \
  "https://api.mayawealth.co.uk/enquiry/v1/integration/organisations/YOUR_ORG_ID/enquiries?status=new&page_size=25"

Windows PowerShell (use single quotes so $ in the key is not treated as a variable):

curl -sS \
  -X GET \
  -H "X-Enquiry-Api-Key: enq_live_YOUR_KEY_HERE" \
  -H "X-Enquiry-Integration-Secret: YOUR_INTEGRATION_SECRET" \
  "https://api.mayawealth.co.uk/enquiry/v1/integration/organisations/YOUR_ORG_ID/enquiries?status=new&page_size=25"

Staff inbox (JWT)

Directory JWT with orgId for the product organisation:

MethodPathPurpose
GET/v1/enquiriesList inbox
GET/v1/enquiries/{id}One submission
PATCH/v1/enquiries/{id}Update status
GET/v1/enquiries/{id}/attachments/{attachmentId}Download attachment

Webhooks

Optional HTTP callbacks for integrators. Configure on the enquiry Worker per site (same pairing as API keys):

SiteURLSigning secret (recommended)
telcamTELCAM_ENQUIRY_WEBHOOK_URLTELCAM_ENQUIRY_WEBHOOK_SECRET
(others){SITE}_ENQUIRY_WEBHOOK_URL{SITE}_ENQUIRY_WEBHOOK_SECRET

Use the same {SITE} spelling as API keys (MAYA_WEALTH_…, TELCAM_AUTO_…, etc.).

Events

EventWhen
enquiry.createdAfter a form is stored (and optional team email)
enquiry.status_changedAfter status changes via integration PATCH or staff PATCH

Delivery

  • POST JSON: { "id", "type", "timestamp", "data": <enquiry> }
  • Headers: X-Enquiry-Event, X-Enquiry-Event-Id, X-Enquiry-Delivery, optional X-Enquiry-Request-Id
  • With a secret: X-Enquiry-Signature: sha256=<hmac-sha256-hex> over the raw request body

Verify HMAC on your endpoint with the shared secret. Failed deliveries are logged on the Worker; there is no retry queue yet — poll the integration list API as a backup.

Attachment bytes are not inlined in webhooks; download via the integration attachment route with the same API key and secret.

Webhook signing secret — any strong random string (for example whsec_ plus 32 bytes of hex):

"whsec_" + (-join ((48..57) + (97..102) | Get-Random -Count 64 | ForEach-Object { [char]$_ }))
npx wrangler secret put TELCAM_ENQUIRY_WEBHOOK_SECRET

OpenAPI on this site documents webhook payloads under Integration → webhooks.


Operator notes

  • Gateway path prefix: /enquiry on https://api.mayawealth.co.uk
  • D1 migrations: pnpm wrangler d1 migrations apply enquiry --remote from apis/enquiry
  • OpenAPI is not served on the live enquiry Worker; use Enquiry API on this documentation site