Customer workspace with a booking page in 10 minutes
Create a customer workspace from an industry template, adjust it with a workspace token, embed the booking page, and hand it over. With curl and Node.
This recipe takes a new customer from order to live booking page with the Partner API. Every API step is shown with curl and with Node. A complete script is at the end.
You will:
- create an API key
- create the customer from an industry template
- read the booking page and meeting types
- get a workspace token
- change the opening hours
- change a meeting type
- embed the booking page
- hand the workspace over
Before you begin
- You are an admin of an approved Partner company. See Partner API.
- For the Node examples you need Node 18 or newer. No packages are needed.
The Node snippets use this small helper. The script at the end includes it.
const BASE = 'https://api.meetergo.com'
async function api(token, method, path, body) {
const res = await fetch(BASE + path, {
method,
headers: {
Authorization: `Bearer ${token}`,
...(body ? { 'Content-Type': 'application/json' } : {}),
},
body: body ? JSON.stringify(body) : undefined,
})
const text = await res.text()
if (!res.ok) throw new Error(`${method} ${path}: ${res.status} ${text}`)
return text ? JSON.parse(text) : null
}
1. Create an API key
- Open Partner portal > API and select Create API key.
- Copy the key. It starts with
mgp_and is shown only once. - Store it on your server, for example as
MEETERGO_PARTNER_KEY.
2. Create the customer from a template
Pick a templateKey: beauty, craftsmen, insurance or consulting. The workspace starts with that industry's meeting types, opening hours and email reminders, in German.
curl -X POST https://api.meetergo.com/v4/partner/customers \
-H "Authorization: Bearer $MEETERGO_PARTNER_KEY" \
-H "Content-Type: application/json" \
-d '{
"requestId": "6f1c2a8e-3b4d-4e5f-8a9b-0c1d2e3f4a5b",
"companyName": "Friseur Muster",
"adminFirstName": "Max",
"adminLastName": "Muster",
"adminEmail": "max@friseur-muster.de",
"language": "de",
"timezone": "Europe/Berlin",
"billingResponsibility": "partner",
"suiteTier": "suite",
"communicationOwner": "partner",
"contactConsentConfirmed": true,
"templateKey": "beauty"
}'
import { randomUUID } from 'node:crypto'
const partnerKey = process.env.MEETERGO_PARTNER_KEY
const requestId = randomUUID() // store it with the order
const created = await api(partnerKey, 'POST', '/v4/partner/customers', {
requestId,
companyName: 'Friseur Muster',
adminFirstName: 'Max',
adminLastName: 'Muster',
adminEmail: 'max@friseur-muster.de',
language: 'de',
timezone: 'Europe/Berlin',
billingResponsibility: 'partner',
suiteTier: 'suite',
communicationOwner: 'partner',
contactConsentConfirmed: true,
templateKey: 'beauty',
})
Create requestId once per order and store it before you call. If the call times out, send it again with the same requestId and body. You get the same customer back, not a second workspace.
3. Read the booking page and meeting types
The response, shortened:
{
"customer": {
"companyId": "3f2b...",
"companyName": "Friseur Muster",
"bookingPageUrl": "https://cal.meetergo.com/..."
},
"setupStatus": "ready",
"adminInviteDelivery": "sent",
"template": {
"key": "beauty",
"meetingTypes": [{ "id": "a91c...", "name": "...", "slug": "..." }]
}
}
const { companyId, bookingPageUrl } = created.customer
const meetingTypes = created.template?.meetingTypes ?? []
If setupStatus is attention_required, setupAttention says what to check.
4. Get a workspace token
The workspace token lets you change this one customer workspace through the Platform API. It is valid for 1 hour.
curl -X POST https://api.meetergo.com/v4/partner/customers/{companyId}/token \
-H "Authorization: Bearer $MEETERGO_PARTNER_KEY"
const { token } = await api(
partnerKey,
'POST',
`/v4/partner/customers/${companyId}/token`,
)
Use token (it starts with mgw_) in the next steps. Do not send the x-meetergo-api-user-id header with it. When it expires, call this endpoint again.
5. Change the opening hours
List the weekly schedules and take the one with isDefault: true:
curl https://api.meetergo.com/availability \
-H "Authorization: Bearer $MEETERGO_WORKSPACE_TOKEN"
Then change the days you need. Days you leave out stay as they are. This opens Saturday from 9 to 13:
curl -X PATCH https://api.meetergo.com/availability/{availabilityId} \
-H "Authorization: Bearer $MEETERGO_WORKSPACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule": {
"saturday": { "enabled": true, "hours": [{ "start": "09:00", "end": "13:00" }] }
}
}'
const schedules = await api(token, 'GET', '/availability')
const hours = schedules.find((s) => s.isDefault) ?? schedules[0]
await api(token, 'PATCH', `/availability/${hours.id}`, {
schedule: {
saturday: { enabled: true, hours: [{ start: '09:00', end: '13:00' }] },
},
})
Times use HH:MM in the schedule's time zone. To close a day, send { "enabled": false }.
6. Change a meeting type
Use an id from template.meetingTypes. Only the fields you send change. This sets the duration to 45 minutes and a new description:
curl -X PATCH https://api.meetergo.com/v4/meeting-type/{meetingTypeId} \
-H "Authorization: Bearer $MEETERGO_WORKSPACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"meetingInfo": {
"duration": 45,
"description": "Waschen, Schneiden, Föhnen."
}
}'
await api(token, 'PATCH', `/v4/meeting-type/${meetingTypes[0].id}`, {
meetingInfo: { duration: 45, description: 'Waschen, Schneiden, Föhnen.' },
})
meetingInfo also takes name. All fields are in the OpenAPI spec.
7. Embed the booking page
Put bookingPageUrl on the customer's website:
<div
style="min-width:330px"
class="meetergo-iframe"
data-src="{bookingPageUrl}"
></div>
<script src="https://cdn.meetergo.com/v4/integration.js"></script>
The booking page takes bookings right away, before the customer signs in.
8. Hand the workspace over
The customer's admin received an invite email in step 2 and sets their own password. You never set or share one.
- If
adminInviteDeliveryisfailed, send the same address toPOST /v4/partner/customers/{companyId}/users. See Troubleshoot the Partner portal. - The customer's admins see your API access and recent changes under Settings > Developer. They can revoke it any time.
The whole flow in one script
Save as setup-customer.mjs and run MEETERGO_PARTNER_KEY=mgp_... node setup-customer.mjs.
import { randomUUID } from 'node:crypto'
const BASE = 'https://api.meetergo.com'
const partnerKey = process.env.MEETERGO_PARTNER_KEY
async function api(token, method, path, body) {
const res = await fetch(BASE + path, {
method,
headers: {
Authorization: `Bearer ${token}`,
...(body ? { 'Content-Type': 'application/json' } : {}),
},
body: body ? JSON.stringify(body) : undefined,
})
const text = await res.text()
if (!res.ok) throw new Error(`${method} ${path}: ${res.status} ${text}`)
return text ? JSON.parse(text) : null
}
// Create the customer. In production, store requestId with the order first.
const requestId = randomUUID()
const created = await api(partnerKey, 'POST', '/v4/partner/customers', {
requestId,
companyName: 'Friseur Muster',
adminFirstName: 'Max',
adminLastName: 'Muster',
adminEmail: 'max@friseur-muster.de',
language: 'de',
timezone: 'Europe/Berlin',
billingResponsibility: 'partner',
suiteTier: 'suite',
communicationOwner: 'partner',
contactConsentConfirmed: true,
templateKey: 'beauty',
})
const { companyId, bookingPageUrl } = created.customer
const meetingTypes = created.template?.meetingTypes ?? []
// Workspace token, valid for 1 hour.
const { token } = await api(
partnerKey,
'POST',
`/v4/partner/customers/${companyId}/token`,
)
// Open on Saturday from 9 to 13.
const schedules = await api(token, 'GET', '/availability')
const hours = schedules.find((s) => s.isDefault) ?? schedules[0]
await api(token, 'PATCH', `/availability/${hours.id}`, {
schedule: {
saturday: { enabled: true, hours: [{ start: '09:00', end: '13:00' }] },
},
})
// First meeting type: 45 minutes.
if (meetingTypes.length > 0) {
await api(token, 'PATCH', `/v4/meeting-type/${meetingTypes[0].id}`, {
meetingInfo: { duration: 45 },
})
}
console.log('requestId:', requestId)
console.log('Admin invite:', created.adminInviteDelivery)
console.log('Embed code:')
console.log(
`<div style="min-width:330px" class="meetergo-iframe" data-src="${bookingPageUrl}"></div>\n` +
'<script src="https://cdn.meetergo.com/v4/integration.js"></script>',
)
Related articles
Was this article helpful?
Let us know if this article answered your questions.