Key Concepts
Authentication
Use a personal access token with the Portals capability (spaces), or a full-access token. A token limited to other capabilities receives 403 This token does not carry the 'spaces' capability.
Create a portal from a template
Build the template in the dashboard (Portals → ⋯ → Save as template), then list and instantiate it:- the previous client’s name in titles, descriptions and steps is replaced by
customerCompanyName - the template’s client-specific branding (logo, colours, backdrop) is dropped and
brandOverridesapplied - action-plan progress starts at zero
Related:
POST /space/{spaceId}/duplicate (same client, “(Copy)” suffix), POST /space/{spaceId}/save-as-template, POST /space/{spaceId}/section-from-template ({ "templateId", "index" }) and POST /space-section-template/from-section for reusable sections.
Control what the client sees
Portals are phase-driven: keep later requirements hidden or locked until the client gets there. Both levels take the same body.Invite the client
https://cal.meetergo.com/spaces/{slug}?invite={inviteToken} (your own domain instead of cal.meetergo.com when a custom domain is configured). Opening it verifies the person’s email without a code; a link with requireEmailOtp asks anyone else for a one-time code.
Read the state of a portal
GET /space/{spaceId} returns sections, blocks and, on task blocks, every step:
assignee.side is them for the client and us for your team. completedAt and updatedAt are set by the server.
Forms. GET /space/{spaceId}/form-status lists every form block in the portal with the submissions made inside this portal: whether the client handed it in, when, by whom, and the answers.
GET /space/{spaceId}/uploads lists what the client uploaded to the upload zone (file name, type, size, who, when). GET /space/{spaceId}/uploads/{uploadId}/download returns a short-lived download URL. Files attached to a form answer arrive with that form’s submission instead.
Follow what the client does
Subscribe to the portal webhooks:space_viewed, space_invite_accepted, space_task_completed, space_task_reopened, space_file_uploaded. A form filled inside a portal arrives as form_submission with a space object naming the portal, block and viewer.
Every portal event carries spaceId, the acting viewer and occurredAt, so it can be matched to your own records without a follow-up request.