Suite
Integrations
Connect any external site so every new enrollment lands here as a draft invoice.
How it works
- In Sources, create a source for the site (e.g.
soulkey) and mark it active. - On that site, store the shared secret as an environment variable named
ENROLLMENT_SECRET. Use the same value that is set here asSOULKEY_WEBHOOK_SECRET. - After a successful enrollment, the site POSTs the payload below to the webhook.
- A draft invoice is created and shows up under Invoices, tagged with the source.
Endpoint
POST https://pay.thehypnoacademy.com/api/public/enrollmentRequired header
X-Enrollment-Secret: <your shared secret>Payload schema
| Field | Type | Required | Notes |
|---|---|---|---|
source | string | yes | Matches a slug in Sources |
id | string | yes | Unique enrollment id (idempotency key) |
fullName | string | yes | |
email | string | yes | |
phone | string | no | |
country | string | no | |
tier | string | no | Package / bundle name (shown on invoice) |
amount | number | no | Ignored for safety; configure pricing in this app |
currency | string (3) | no | ISO code, default USD |
description | string | no | Overrides invoice line label |
meta | object | no | Arbitrary extra data, stored on invoice |
Copy-paste snippets
Paste this into the chat of any other Lovable project to wire it up.
When a new enrollment is completed on this site, send it to my invoicing app so a draft invoice is created automatically.
Add a server-side handler that POSTs to:
https://pay.thehypnoacademy.com/api/public/enrollment
Headers:
Content-Type: application/json
X-Enrollment-Secret: <value of the ENROLLMENT_SECRET env var / Lovable Cloud secret>
Body (JSON):
{
"source": "soulkey", // identifies this site in my dashboard
"id": "<unique enrollment id>", // used as idempotency key
"fullName": "<full name>",
"email": "<email>",
"phone": "<phone, optional>",
"country": "<country, optional>",
"tier": "<package or tier name, optional>",
"currency": "<3-letter ISO code, optional, default USD>"
}
Requirements:
- Call this from server-side code only (server function / edge function / API route). Never from the browser.
- Add ENROLLMENT_SECRET as a secret in Lovable Cloud (do not hardcode).
- Treat any non-2xx response as a failure and log the response body for debugging.
- The same "id" must always represent the same enrollment so retries do not create duplicates.
- Do not send invoice pricing from the website; this app calculates pricing from the source settings / server-side rules.Responses
200— invoice created (or deduped if the sameidwas sent before).400— invalid JSON or payload failed validation.401— missing or wrongX-Enrollment-Secret.403— unknown source slug, or the source is disabled in the dashboard.500— server error; the response body includes details.
Team Staff Suite sync
A secured read-only API (plus limited write) so the Staff Suite works off this database — one source of truth, no duplicated invoices and no drift.
Base URL & auth header
https://pay.thehypnoacademy.com/api/public/sync
X-Sync-Secret: <value of STAFF_SUITE_SYNC_SECRET>The secret is stored here as STAFF_SUITE_SYNC_SECRET. Add the same value as a secret in the Staff Suite — never hardcode it or call these endpoints from the browser.
Endpoints
GET /invoices— list withlimit,offset,updated_since,status,include=items,fees,customers.GET /customers— list withlimit,offset,updated_since,search.GET /invoices/:id— one invoice with customer, items, fees and timeline.PATCH /invoices/:id— limited write: status, payment method/note, notes, reminders toggle.
Connect this app to my invoicing app (InvoiceSuite) so it reads live invoice and customer data instead of keeping its own copies.
Base URL: https://pay.thehypnoacademy.com/api/public/sync
Auth header on every request: X-Sync-Secret: <value of the STAFF_SUITE_SYNC_SECRET env var>
Store that value as a Lovable Cloud secret named STAFF_SUITE_SYNC_SECRET. Call these endpoints from server-side code only — never from the browser.
Endpoints:
GET /invoices?limit=100&offset=0&updated_since=<ISO date>&status=<status>&include=items,fees,customers
-> { invoices: [...], items?, fees?, customers?, count, limit, offset, synced_at }
Each invoice includes public_url (the customer-facing payment link).
GET /customers?limit=200&offset=0&updated_since=<ISO date>&search=<name or email>
-> { customers: [...], count, limit, offset, synced_at }
GET /invoices/<invoice id>
-> { invoice, customer, items, fees, events }
PATCH /invoices/<invoice id>
Body (all fields optional): { "status": "draft|awaiting_approval|approved|sent|paid|cancelled",
"payment_method": "...", "payment_note": "...", "notes": "...",
"reminders_enabled": true, "actor": "<staff member name>" }
-> { ok: true, invoice }
Requirements:
- Read data live through these endpoints; do not duplicate invoices into a local table (cache briefly if needed).
- Use updated_since with the previous synced_at value for incremental polling.
- Always send "actor" on PATCH so the change is attributed in the invoice timeline.
- Treat any non-2xx as a failure and log the response body.