Docs

Authoring API reference

The authoring API creates and edits draft tours and checklists with a workspace API key. It is the same surface the MCP server uses. It has no publish operation: a person reviews each draft and publishes it from the dashboard.

Quickstart

Create a Read & write key under Settings, then API keys, then:

Terminal
export STEPPR_API_KEY=stp_api_YOUR_KEY

# 1. Check the key: which workspace, which plan, read or write.
curl https://api.steppr.io/api/v1/workspace \
  -H "Authorization: Bearer $STEPPR_API_KEY"

# 2. Create a draft tour with all of its steps in one call.
curl -X POST https://api.steppr.io/api/v1/tours \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Create your first project",
  "steps": [
    {
      "type": "tooltip",
      "selector": "[data-testid=\"new-project-button\"]",
      "title": "Start a project",
      "body": "Projects hold your boards and files. Click **New project** to create one.",
      "config": {
        "advanceOn": "anchor-click"
      }
    },
    {
      "type": "tooltip",
      "selector": "[data-testid=\"project-name-input\"]",
      "title": "Name it",
      "body": "Give the project a name. You can rename it later.",
      "config": {
        "requireToAdvance": {
          "type": "anchor_has_value"
        }
      }
    },
    {
      "type": "modal",
      "title": "Project created",
      "body": "Invite a teammate from the **Team** page when you are ready."
    }
  ],
  "targeting": [
    {
      "type": "url_match",
      "pattern": "/projects",
      "match": "contains"
    }
  ],
  "triggers": [
    {
      "type": "page_load"
    }
  ]
}'

The second call answers 201 with the full tour. Open tour.links.previewUrl to see the draft on your own site, or tour.links.dashboardUrl to open it in the editor. The review and publish section of the MCP guide applies to drafts created this way too.

Authentication

Send the key as a Bearer token on every request. Keys start with stp_api_.

Header
Authorization: Bearer stp_api_YOUR_KEY
  • The key identifies the workspace, so there is no workspace id or slug in any path.
  • Read only keys (role viewer) can call every GET endpoint. Read & write keys (role editor) can call everything on this page.
  • Writes also need an active subscription or trial. Otherwise they return 403 SUBSCRIPTION_INACTIVE while reads continue to work.
  • Keys work only on /api/v1 and the MCP server. Every other Steppr endpoint rejects them, which keeps billing, team members and key management out of reach.
  • This is a server-side API. Do not call it from a browser or ship a key in front-end code. The public project key in your install snippet is a different credential and does not work here.

Requests and responses

  • Base URL: https://api.steppr.io/api/v1
  • Request and response bodies are JSON, except GET /authoring-guide, which returns Markdown. Request bodies are limited to 256 KB.
  • Ids are UUIDs. Timestamps are ISO 8601 strings in UTC.
  • Successful responses wrap the result in a named key: { tours }, { tour }, { checklists } or { checklist }.
  • Endpoints that create something answer 201. Everything else answers 200.
  • Every endpoint that changes a tour or its steps returns the full updated tour, so you always hold the current step ids and order without a second request.
  • String fields are trimmed before validation.

Errors

Errors have the shape { error, code, details? }. error is a message for people, code is stable and meant for your code to branch on, and details is present on some codes.

400 Bad Request
{
  "error": "Invalid body",
  "code": "BAD_REQUEST",
  "details": {
    "formErrors": [],
    "fieldErrors": {
      "steps": [
        "Array must contain at least 1 element(s)"
      ]
    }
  }
}
403 Forbidden
{
  "error": "This API key is read-only",
  "code": "FORBIDDEN"
}
StatusCodeMeaning
400BAD_REQUESTThe body failed validation, in which case details holds formErrors and fieldErrors. Also returned for content that is well formed but wrong, such as a reorder that omits a step or a checklist item pointing at a tour that is not in the workspace.
400TOUR_CAP_REACHEDThe plan's tour limit is reached. Drafts count. details.cap is the limit.
400CHECKLIST_CAP_REACHEDThe plan's checklist limit is reached. details.cap is the limit.
400CHECKLIST_ITEM_CAP_REACHEDMore items than the plan allows in one checklist. details.cap is the limit.
401UNAUTHORIZEDThe key is missing, malformed, unknown or revoked.
403FORBIDDENA Read only key was used on a write endpoint.
403SUBSCRIPTION_INACTIVEThe trial has ended or the subscription has lapsed. The workspace is read only until it is reactivated.
403FEATURE_GATEDThe request includes an event trigger and the plan does not include event triggers. They are available on Growth and above, and during the trial.
404NOT_FOUNDNo tour, step or checklist with that id exists in this workspace. An id that is not a UUID also gets this response.
429RATE_LIMITEDSee the rate limit below.
500INTERNALA failure on our side. Retrying once is reasonable.

Rate limit

120 requests per minute per IP address. Responses carry the standard RateLimit and RateLimit-Policy headers. Over the limit, the API answers 429 with code RATE_LIMITED. The MCP server has the same limit, counted separately.

Objects

Tour

Tour
{
  "id": "4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34",
  "name": "Create your first project",
  "status": "draft",
  "lastPublishedAt": null,
  "createdAt": "2026-09-19T09:14:03.000Z",
  "updatedAt": "2026-09-19T09:14:03.000Z",
  "targeting": [
    {
      "type": "url_match",
      "pattern": "/projects",
      "match": "contains"
    }
  ],
  "triggers": [
    {
      "type": "page_load"
    }
  ],
  "steps": [
    {
      "id": "a1f4c2d8-3b6e-4a90-8c15-7e2d9b04f6a1",
      "order": 0,
      "type": "tooltip",
      "selector": "[data-testid=\"new-project-button\"]",
      "title": "Start a project",
      "body": "Projects hold your boards and files. Click **New project** to create one.",
      "config": {
        "advanceOn": "anchor-click"
      }
    },
    {
      "id": "b7e9d3a2-5c18-4f6b-9d24-1a8c3e5f7b92",
      "order": 1,
      "type": "tooltip",
      "selector": "[data-testid=\"project-name-input\"]",
      "title": "Name it",
      "body": "Give the project a name. You can rename it later.",
      "config": {
        "requireToAdvance": {
          "type": "anchor_has_value"
        }
      }
    },
    {
      "id": "c3d8e1f6-9a27-4b5c-8e31-6f4a2b9d0c83",
      "order": 2,
      "type": "modal",
      "selector": null,
      "title": "Project created",
      "body": "Invite a teammate from the **Team** page when you are ready.",
      "config": {}
    }
  ],
  "hasUnpublishedChanges": false,
  "links": {
    "dashboardUrl": "https://app.steppr.io/app/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34",
    "previewUrl": "https://app.example.com/?steppr_preview=4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34&steppr_preview_token=eyJ0b3VySWQi...",
    "previewExpiresAt": "2026-09-20T09:14:03.000Z"
  }
}
FieldTypeNotes
statusdraft | published | archivedRead only. The API cannot change it.
hasUnpublishedChangesbooleanTrue when the tour is published and its draft differs from what is live. API edits only ever change the draft.
links.dashboardUrlstringThe tour in the dashboard editor. Does not expire.
links.previewUrlstring | nullOpens your site with the draft rendered by the snippet. Null when the workspace has no allowed origin that is a full origin, when the key is Read only, or when the subscription is not active.
links.previewExpiresAtstring | nullPreview links last 24 hours. Every response that includes the tour carries a fresh one.

List responses use a summary without steps, targeting, triggers or links, and with a stepCount instead.

Step

FieldTypeNotes
typetooltip | modal | hotspotRequired. A tooltip points at an element. A hotspot is a pulsing marker that opens its card when clicked. A modal is a centred card and ignores any selector.
selectorstring | nullCSS selector, 1 to 1024 characters. The API accepts a tooltip or hotspot without one, but it then renders as a centred card. Must match one element; the snippet uses the first match.
titlestring | nullPlain text, up to 200 characters.
bodystring | nullUp to 4000 characters. Inline Markdown only: bold, italic, code and links.
configobjectOptional. Recognised keys are listed below; unknown keys are stored and ignored.
orderintegerResponse only. 0-based position in the tour.

Selectors should follow the same priority as the click-to-build picker: a data-testid attribute, then a stable id, then a short chain of stable classes. Elements inside a Shadow DOM or a cross-origin iframe on your site cannot be targeted.

Step config

KeyValueEffect
buttonsArray of { kind, label }, kind is next, prev or dismissButtons in display order. When omitted the card has one button labelled Next, or Finish on the last step.
showButtonsboolean, default trueFalse hides the button row. Only useful together with anchor-click advance.
advanceOnbutton (default) or anchor-clickWith anchor-click the step advances when the user clicks the target element, and the click still performs its normal action. Tooltip and hotspot only.
requireToAdvance{ "type": "anchor_has_value" }, { "type": "event", "name": "…" } or nullKeeps the next button disabled until the target input has a value, or until your app calls Steppr.track() with that event name.
imageUrl, imageAltAbsolute https URL; stringAn image in the card and its alt text. Steppr does not host the image.
imagePosition, imageHref, imageHrefTargettop | bottom; URL or path; blank | selfWhere the image sits, and an optional link for it.

Targeting rules

targeting is an array of up to 50 rules. All of them must match for a user to be eligible. An empty array means everyone.

Targeting rules
[
  {
    "type": "url_match",
    "pattern": "/projects",
    "match": "contains"
  },
  {
    "type": "trait",
    "key": "plan",
    "op": "eq",
    "value": "pro"
  }
]
  • url_match: pattern is 1 to 2048 characters and match is exact, contains or regex. The pattern is compared with the full page URL, so contains with a path fragment is usually the right choice.
  • trait: key is 1 to 128 characters, op is eq, neq, contains or exists, and value is an optional string, ignored for exists. Traits come from your Steppr.identify() call and are compared as strings.

Trigger rules

triggers is an array of up to 50 rules on tours. Any one of them starts the tour for an eligible user. A tour with no triggers never starts on its own and the dashboard will not publish it, so send at least one.

Trigger rules
[
  {
    "type": "page_load"
  },
  {
    "type": "url_match",
    "pattern": "/projects/new",
    "match": "contains"
  },
  {
    "type": "event",
    "name": "project_created"
  }
]
  • page_load fires on page load and on each route change in a single-page app.
  • url_match takes the same pattern and match fields as the targeting rule.
  • event fires when your app calls Steppr.track(name). name is 1 to 128 characters. Requires Growth or above; on Starter the request fails with FEATURE_GATED.

Checklist

Checklist
{
  "id": "e8b3c6d1-7f42-4a9e-b153-9c2d5e8f1a65",
  "name": "Get started",
  "status": "draft",
  "createdAt": "2026-09-19T09:20:41.000Z",
  "updatedAt": "2026-09-19T09:20:41.000Z",
  "targeting": [
    {
      "type": "url_match",
      "pattern": "/",
      "match": "contains"
    }
  ],
  "items": [
    {
      "id": "f2c7a9e3-4d58-4b16-8a07-3e9b1d6c5f28",
      "order": 0,
      "title": "Create your first project",
      "description": "Takes about a minute.",
      "actionType": "tour",
      "actionValue": "4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34"
    },
    {
      "id": "0a6d4b9f-2c71-4e83-9b35-5f8e2a7c1d49",
      "order": 1,
      "title": "Open the team page",
      "description": null,
      "actionType": "url",
      "actionValue": "/team"
    },
    {
      "id": "1b8e5c3a-6f92-4d07-a418-7c4d9e2b6f50",
      "order": 2,
      "title": "Send your first invite",
      "description": null,
      "actionType": "event",
      "actionValue": "invite_sent"
    }
  ],
  "links": {
    "dashboardUrl": "https://app.steppr.io/app/checklists/e8b3c6d1-7f42-4a9e-b153-9c2d5e8f1a65"
  }
}
actionTypeactionValueThe item completes when
tourId of a tour in this workspaceThe user finishes that tour. Clicking the item starts it.
urlA path or absolute URLThe page URL contains the value. Clicking the item navigates there.
eventAn event nameYour app calls Steppr.track() with that name.

Checklists have targeting but no triggers, and links contains only dashboardUrl. List responses use a summary with an itemCount instead of items, targeting and links.

Workspace and guide

GET/workspace

Identifies the key. Use it to check a key before doing anything else. role is editor for Read & write keys and viewer for Read only keys.

Request
curl https://api.steppr.io/api/v1/workspace \
  -H "Authorization: Bearer $STEPPR_API_KEY"
200 OK
{
  "workspace": {
    "slug": "acme",
    "plan": "starter",
    "subscriptionStatus": "active"
  },
  "role": "editor"
}

GET/authoring-guide

Returns the authoring guide as text/markdown. It is written for coding agents and is the same document the MCP tool get_authoring_guide returns: step types, selector rules, config keys, copy limits and worked examples.

Request
curl https://api.steppr.io/api/v1/authoring-guide \
  -H "Authorization: Bearer $STEPPR_API_KEY"

Install

GET/install

The workspace public key, SDK URL, API URL, a ready-to-paste script tag and the current allowed origins. Steppr renders nothing until the snippet is in your app and the app's origin is allowed.

Request
curl https://api.steppr.io/api/v1/install \
  -H "Authorization: Bearer $STEPPR_API_KEY"
200 OK
{
  "install": {
    "publicKey": "stp_live_79ef9d998ea14f1e",
    "sdkUrl": "https://www.steppr.io/steppr.js",
    "apiUrl": "https://api.steppr.io",
    "snippet": "<script\n  src=\"https://www.steppr.io/steppr.js\"\n  data-project-key=\"stp_live_79ef9d998ea14f1e\"\n  async\n></script>",
    "allowedOrigins": [
      "http://localhost:3001",
      "https://app.acme.com"
    ],
    "originCap": 10
  }
}

POST/origins

Appends one origin to the allowlist. Must be scheme, host and optional port with no path (http://localhost:3001, https://app.example.com); wildcard subdomains such as https://*.example.com are accepted. Adding an origin that is already listed succeeds without change. Origins can only be removed in the dashboard. Returns the same body as GET /install; fails with ORIGIN_CAP_REACHED at 10 origins.

Request
curl -X POST https://api.steppr.io/api/v1/origins \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "origin": "http://localhost:3001"
}'

Tours

GET/tours

Lists every tour in the workspace, whatever its status.

Request
curl https://api.steppr.io/api/v1/tours \
  -H "Authorization: Bearer $STEPPR_API_KEY"
200 OK
{
  "tours": [
    {
      "id": "4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34",
      "name": "Create your first project",
      "status": "draft",
      "stepCount": 3,
      "lastPublishedAt": null,
      "createdAt": "2026-09-19T09:14:03.000Z",
      "updatedAt": "2026-09-19T09:14:03.000Z"
    }
  ]
}

POST/tours

Creates a draft tour with all of its steps. The tour and steps are written in one transaction, so a rejected request creates nothing. The new tour counts towards the plan's tour limit.

FieldTypeNotes
namestringRequired. 2 to 120 characters. Internal; end users never see it.
stepsStep[]Required. 1 to 50 steps, in order.
targetingTargetingRule[]Optional. Up to 50 rules.
triggersTriggerRule[]Optional, but a tour needs at least one before it can be published.
Request
curl -X POST https://api.steppr.io/api/v1/tours \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Create your first project",
  "steps": [
    {
      "type": "tooltip",
      "selector": "[data-testid=\"new-project-button\"]",
      "title": "Start a project",
      "body": "Projects hold your boards and files. Click **New project** to create one.",
      "config": {
        "advanceOn": "anchor-click"
      }
    },
    {
      "type": "tooltip",
      "selector": "[data-testid=\"project-name-input\"]",
      "title": "Name it",
      "body": "Give the project a name. You can rename it later.",
      "config": {
        "requireToAdvance": {
          "type": "anchor_has_value"
        }
      }
    },
    {
      "type": "modal",
      "title": "Project created",
      "body": "Invite a teammate from the **Team** page when you are ready."
    }
  ],
  "targeting": [
    {
      "type": "url_match",
      "pattern": "/projects",
      "match": "contains"
    }
  ],
  "triggers": [
    {
      "type": "page_load"
    }
  ]
}'
201 Created
{
  "tour": {
    "id": "4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34",
    "name": "Create your first project",
    "status": "draft",
    "lastPublishedAt": null,
    "createdAt": "2026-09-19T09:14:03.000Z",
    "updatedAt": "2026-09-19T09:14:03.000Z",
    "targeting": [
      {
        "type": "url_match",
        "pattern": "/projects",
        "match": "contains"
      }
    ],
    "triggers": [
      {
        "type": "page_load"
      }
    ],
    "steps": [
      {
        "id": "a1f4c2d8-3b6e-4a90-8c15-7e2d9b04f6a1",
        "order": 0,
        "type": "tooltip",
        "selector": "[data-testid=\"new-project-button\"]",
        "title": "Start a project",
        "body": "Projects hold your boards and files. Click **New project** to create one.",
        "config": {
          "advanceOn": "anchor-click"
        }
      },
      {
        "id": "b7e9d3a2-5c18-4f6b-9d24-1a8c3e5f7b92",
        "order": 1,
        "type": "tooltip",
        "selector": "[data-testid=\"project-name-input\"]",
        "title": "Name it",
        "body": "Give the project a name. You can rename it later.",
        "config": {
          "requireToAdvance": {
            "type": "anchor_has_value"
          }
        }
      },
      {
        "id": "c3d8e1f6-9a27-4b5c-8e31-6f4a2b9d0c83",
        "order": 2,
        "type": "modal",
        "selector": null,
        "title": "Project created",
        "body": "Invite a teammate from the **Team** page when you are ready.",
        "config": {}
      }
    ],
    "hasUnpublishedChanges": false,
    "links": {
      "dashboardUrl": "https://app.steppr.io/app/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34",
      "previewUrl": "https://app.example.com/?steppr_preview=4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34&steppr_preview_token=eyJ0b3VySWQi...",
      "previewExpiresAt": "2026-09-20T09:14:03.000Z"
    }
  }
}

GET/tours/:tourId

Returns one tour with its steps, targeting, triggers and a fresh preview link.

Request
curl https://api.steppr.io/api/v1/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34 \
  -H "Authorization: Bearer $STEPPR_API_KEY"

The response is { tour }, as shown for create.

PATCH/tours/:tourId

Updates name, targeting or triggers. All three are optional, and an array you send replaces the existing one. Any other key, including status, is rejected with 400 BAD_REQUEST.

Request
curl -X PATCH https://api.steppr.io/api/v1/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34 \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Create your first project (v2)",
  "targeting": [
    {
      "type": "url_match",
      "pattern": "/projects",
      "match": "contains"
    },
    {
      "type": "trait",
      "key": "plan",
      "op": "eq",
      "value": "pro"
    }
  ]
}'

The response is the updated { tour }.

Steps

All four step endpoints return the full updated { tour }.

POST/tours/:tourId/steps

Adds a step. The body is a step plus an optional position, a 0-based index from 0 to 200. With a position the step is inserted there and later steps shift down. Without one, or with a position past the end, it is appended. Answers 201.

Request
curl -X POST https://api.steppr.io/api/v1/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34/steps \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "hotspot",
  "selector": "#project-templates",
  "title": "Templates",
  "body": "Start from a template instead of a blank project.",
  "position": 1
}'

PATCH/tours/:tourId/steps/:stepId

Changes any of type, selector, title, body and config. Fields you leave out are unchanged.

Request
curl -X PATCH https://api.steppr.io/api/v1/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34/steps/b7e9d3a2-5c18-4f6b-9d24-1a8c3e5f7b92 \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "selector": "[data-testid=\"project-name-field\"]",
  "body": "Give the project a name. You can change it later in project settings."
}'
config is replaced, not merged. When you send config, include every key you want to keep.

DELETE/tours/:tourId/steps/:stepId

Removes the step. There is no request body.

Request
curl -X DELETE https://api.steppr.io/api/v1/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34/steps/b7e9d3a2-5c18-4f6b-9d24-1a8c3e5f7b92 \
  -H "Authorization: Bearer $STEPPR_API_KEY"

POST/tours/:tourId/steps/reorder

Sets the order of the steps. stepIds must contain every step id of the tour exactly once, otherwise the request fails with 400 BAD_REQUEST.

Request
curl -X POST https://api.steppr.io/api/v1/tours/4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34/steps/reorder \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "stepIds": [
    "a1f4c2d8-3b6e-4a90-8c15-7e2d9b04f6a1",
    "b7e9d3a2-5c18-4f6b-9d24-1a8c3e5f7b92",
    "d5a2b8c4-1e39-4d7a-a642-8b3f6c1e9d74",
    "c3d8e1f6-9a27-4b5c-8e31-6f4a2b9d0c83"
  ]
}'

Checklists

GET/checklists

Lists every checklist in the workspace.

Request
curl https://api.steppr.io/api/v1/checklists \
  -H "Authorization: Bearer $STEPPR_API_KEY"
200 OK
{
  "checklists": [
    {
      "id": "e8b3c6d1-7f42-4a9e-b153-9c2d5e8f1a65",
      "name": "Get started",
      "status": "draft",
      "itemCount": 3,
      "createdAt": "2026-09-19T09:20:41.000Z",
      "updatedAt": "2026-09-19T09:20:41.000Z"
    }
  ]
}

POST/checklists

Creates a draft checklist with all of its items in one transaction. Both the plan's checklist limit and its items-per-checklist limit apply. An item with actionType: "tour" must point at a tour that already exists in the workspace, so create the tour first.

FieldTypeNotes
namestringRequired. 2 to 120 characters.
itemsItem[]Required. 1 to 50 items, in order, subject to the plan’s item limit.
items[].titlestringRequired. 1 to 200 characters.
items[].descriptionstring | nullOptional. Up to 2000 characters, same inline Markdown as step bodies.
items[].actionTypetour | url | eventRequired.
items[].actionValuestringRequired. 1 to 2048 characters. Meaning depends on actionType, see the checklist object.
targetingTargetingRule[]Optional. Up to 50 rules.
Request
curl -X POST https://api.steppr.io/api/v1/checklists \
  -H "Authorization: Bearer $STEPPR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Get started",
  "items": [
    {
      "title": "Create your first project",
      "description": "Takes about a minute.",
      "actionType": "tour",
      "actionValue": "4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34"
    },
    {
      "title": "Open the team page",
      "actionType": "url",
      "actionValue": "/team"
    },
    {
      "title": "Send your first invite",
      "actionType": "event",
      "actionValue": "invite_sent"
    }
  ],
  "targeting": [
    {
      "type": "url_match",
      "pattern": "/",
      "match": "contains"
    }
  ]
}'
201 Created
{
  "checklist": {
    "id": "e8b3c6d1-7f42-4a9e-b153-9c2d5e8f1a65",
    "name": "Get started",
    "status": "draft",
    "createdAt": "2026-09-19T09:20:41.000Z",
    "updatedAt": "2026-09-19T09:20:41.000Z",
    "targeting": [
      {
        "type": "url_match",
        "pattern": "/",
        "match": "contains"
      }
    ],
    "items": [
      {
        "id": "f2c7a9e3-4d58-4b16-8a07-3e9b1d6c5f28",
        "order": 0,
        "title": "Create your first project",
        "description": "Takes about a minute.",
        "actionType": "tour",
        "actionValue": "4c9f2a6e-8b1d-4e3a-9f70-2d5b8c1e6a34"
      },
      {
        "id": "0a6d4b9f-2c71-4e83-9b35-5f8e2a7c1d49",
        "order": 1,
        "title": "Open the team page",
        "description": null,
        "actionType": "url",
        "actionValue": "/team"
      },
      {
        "id": "1b8e5c3a-6f92-4d07-a418-7c4d9e2b6f50",
        "order": 2,
        "title": "Send your first invite",
        "description": null,
        "actionType": "event",
        "actionValue": "invite_sent"
      }
    ],
    "links": {
      "dashboardUrl": "https://app.steppr.io/app/checklists/e8b3c6d1-7f42-4a9e-b153-9c2d5e8f1a65"
    }
  }
}

GET/checklists/:checklistId

Returns one checklist as { checklist } with its items, targeting and dashboard link.

Request
curl https://api.steppr.io/api/v1/checklists/e8b3c6d1-7f42-4a9e-b153-9c2d5e8f1a65 \
  -H "Authorization: Bearer $STEPPR_API_KEY"

Not in the API

  • Publishing or archiving tours and checklists, or changing their status in any other way.
  • Deleting tours or checklists.
  • Editing a checklist or its items after creation.
  • Announcements.
  • Theme presets, tour chaining, analytics and workspace settings.

All of these are available in the dashboard. If you need one of them in the API, tell us what you are building at hello@steppr.io.

Try it on your own app.

The trial runs 7 days and does not ask for a card. API keys and the MCP server are available during the trial.