GuideMark

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 pathScopeDoes
GET /toursreadAll tours, drafts included, newest change first, without steps
POST /tourswrite_draftsCreate a tour with all its steps; a draft unless "publish": true (needs publishing rights). 201
GET /tours/:idreadOne tour with its steps
PUT /tours/:idwrite_draftsReplace title, pageUrl and all steps. Live tours need publishing rights
DELETE /tours/:idwrite_draftsDelete. Live tours need publishing rights
POST /tours/:id/publishpublishing rightsPut live; switches off the page's other live tour
POST /tours/:id/unpublishpublishing rightsBack to draft
POST /tours/:id/request-reviewwrite_draftsEmail the owner to review this draft (details)

Tour body (POST, PUT)

FieldTypeRules
titlestring3–200 characters
pageUrlstringA path on the project's domain: starts with /, no spaces, no .., up to 2048 characters
stepsarrayUp to 200 steps, in order
steps[].targetstringCSS selector, required, up to 4000 characters
steps[].contentstringStep text, plain text (HTML tags show literally), up to 20000 characters
steps[].actionclick | hover | typeDefault click
steps[].actionValuestring | nullFor type: the text to type
steps[].namestring | nullShort label, up to 200 characters
publishbooleanPOST 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 pathScopeDoes
GET /beaconsreadAll tooltips, drafts included
POST /beaconswrite_draftsCreate; a draft unless "publish": true (needs publishing rights). 201
PATCH /beacons/:idwrite_draftsChange any fields. Live tooltips need publishing rights
DELETE /beacons/:idwrite_draftsDelete. Live tooltips need publishing rights
POST /beacons/:id/publish · /unpublishpublishing rightsPut live or back to draft
POST /beacons/:id/request-reviewwrite_draftsEmail the owner to review this draft

Tooltip body

FieldTypeRules
titlestringRequired on create, up to 200 characters
contentstringRequired on create, up to 5000 characters
targetSelectorstringRequired on create, up to 4000 characters
pageUrlstring | nullA path; null or empty shows it on every page
triggerbeacon | hover | clickDefault beacon
deliveryalways | first_time | sessionDefault always
publishbooleanPOST only. Default false

Publishing is never a field on update: use the publish and unpublish endpoints.