REST API
Every /api/v1 endpoint for tours and beacon tooltips, with request and response shapes.
Base URL: https://guidemark.co/api/v1. Authenticate every request with an API key:
-H "Authorization: Bearer gm_…"A key belongs to one project, so endpoints never take a project ID. Request and response bodies are JSON. Errors are { "error": "…" }; see Errors and limits. Permissions follow Drafts and publishing.
The same API is described in OpenAPI 3.1 at /api/v1/openapi.json: every endpoint, its scope, request body, response shape and error codes. Point a coding agent or an OpenAPI client generator at it. It needs no key.
Project
GET /project
{
"id": "f40f040d-…",
"name": "Ledgerloop",
"domain": "https://ledgerloop-demo.pages.dev",
"agentPublishPolicy": "drafts_only",
"key": { "scopes": ["read", "write_drafts"], "canPublish": false }
}canPublish is true only when the key has publish and the policy is publish.
Tours
A tour in responses:
{
"id": "d127bb48-…",
"shortId": "mYYDr",
"title": "Pricing: pick your plan",
"pageUrl": "/pricing",
"status": "draft",
"playBehavior": "first_time",
"showPlaybackButton": false,
"createdAt": "2026-10-28T15:50:17Z",
"updatedAt": "2026-10-28T15:50:17Z",
"steps": [
{ "target": "#plan-studio", "content": "Most teams start here.", "action": "click", "actionValue": null, "name": null }
]
}status is published (live) or draft. steps appear only when fetching one tour or after a write.
| Method and path | Scope | Does |
|---|---|---|
GET /tours | read | All tours, drafts included, newest change first, without steps |
POST /tours | write_drafts | Create a tour with all its steps; a draft unless "publish": true (needs publishing rights). 201 |
GET /tours/:id | read | One tour with its steps |
PUT /tours/:id | write_drafts | Replace title, pageUrl and all steps. Live tours need publishing rights |
DELETE /tours/:id | write_drafts | Delete. Live tours need publishing rights |
POST /tours/:id/publish | publishing rights | Put live; switches off the page's other live tour |
POST /tours/:id/unpublish | publishing rights | Back to draft |
POST /tours/:id/request-review | write_drafts | Email the owner to review this draft (details) |
Tour body (POST, PUT)
| Field | Type | Rules |
|---|---|---|
title | string | 3–200 characters |
pageUrl | string | A path on the project's domain: starts with /, no spaces, no .., up to 2048 characters |
steps | array | Up to 200 steps, in order |
steps[].target | string | CSS selector, required, up to 4000 characters |
steps[].content | string | Step text, plain text (HTML tags show literally), up to 20000 characters |
steps[].action | click | hover | type | Default click |
steps[].actionValue | string | null | For type: the text to type |
steps[].name | string | null | Short label, up to 200 characters |
publish | boolean | POST only. Default false |
curl -X POST https://guidemark.co/api/v1/tours \
-H "Authorization: Bearer gm_…" -H "Content-Type: application/json" \
-d '{"title":"Pick your plan","pageUrl":"/pricing","steps":[{"target":"#plan-studio","content":"Most teams start here."}]}'Beacon tooltips
A tooltip in responses:
{
"id": "…", "title": "Export", "content": "Downloads every invoice as CSV.",
"targetSelector": "[data-testid=export-csv]", "pageUrl": "/invoices",
"trigger": "beacon", "delivery": "always", "status": "draft",
"createdAt": "…", "updatedAt": "…"
}| Method and path | Scope | Does |
|---|---|---|
GET /beacons | read | All tooltips, drafts included |
POST /beacons | write_drafts | Create; a draft unless "publish": true (needs publishing rights). 201 |
PATCH /beacons/:id | write_drafts | Change any fields. Live tooltips need publishing rights |
DELETE /beacons/:id | write_drafts | Delete. Live tooltips need publishing rights |
POST /beacons/:id/publish · /unpublish | publishing rights | Put live or back to draft |
POST /beacons/:id/request-review | write_drafts | Email the owner to review this draft |
Tooltip body
| Field | Type | Rules |
|---|---|---|
title | string | Required on create, up to 200 characters |
content | string | Required on create, up to 5000 characters |
targetSelector | string | Required on create, up to 4000 characters |
pageUrl | string | null | A path; null or empty shows it on every page |
trigger | beacon | hover | click | Default beacon |
delivery | always | first_time | session | Default always |
publish | boolean | POST only. Default false |
Publishing is never a field on update: use the publish and unpublish endpoints.