Skip to content

API reference Overview

API reference

API reference

How to call the API with a workspace token: requests, permissions, limits, filters, errors, and every operation.

Everything a workspace token can do: 77 operations. The same list is behind the MCP server and the command line tool, so all three always match. A machine-readable copy is at /api/v1/openapi.json.

Making a request #

Every operation is a POST to https://clearsaga.com/api/v1/<name> with a JSON object as its body, reads included. No body means an empty object. The answer is a JSON object with status 200.

Create a token in the dashboard under Settings, Agent access, and send it in the Authorization header. That header is the only place a token is read from: never put one in a web address.

curl -s -X POST https://clearsaga.com/api/v1/sites.list \
  -H "Authorization: Bearer clearsaga_pat_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Start with sites.list: every operation about one site needs a siteId, and the ids come from there. Times in answers are milliseconds since 1970 UTC. Dates you send are YYYY-MM-DD in the time zone of the site.

Tokens #

A token belongs to one workspace and has one or both of two permissions.

  • Read: list the sites of the workspace and read every report, revenue included.
  • Write: Create, change and delete funnels, campaign links, conversion goals, chart notes, saved segments and alert rules. Create and change store costs. Includes Read.

A token stops working when it is revoked, and when the person who created it leaves the workspace, is removed or becomes a Viewer. The API remembers a token for up to 60 seconds, so a change like that can take that long to reach it. "Last used" on the Agent access page is approximate: it is written at most every 5 minutes.

Every change made with a token is recorded with the name of the token and shown under Settings, Agent access. Reads are not recorded.

A delete removes for good and cannot be undone. It is recorded with the name of what was removed. Only the definition goes, and with an alert rule its delivery log: no recorded visit, event or order is touched.

What a token can never do #

  • See or change another workspace. A token belongs to exactly one.
  • Use a share link or the public demo in place of a site id.
  • Export CSV files.
  • Create, list or revoke tokens.
  • Invite, remove or change members.
  • Change the plan or anything about billing.
  • Create, rename, reset or delete a site.
  • Change tracking options, exclusions, revenue settings or notification settings.
  • Enable, change or revoke share links or embed widgets.
  • Rename or delete a preset conversion goal.
  • Record an order.
  • Connect a store or replace its secret.
  • Read anything that names a person. Visitor profiles, where a site switched them on, are a random id with a generated name, places, devices and pages.

Dashboard actions that are closed to tokens, and why:

Action Why
Get install status Install screen helper; returns the last hostname and the drop counters; sites.get says whether hits arrive.
Get snippet Install screen helper; the text embeds the site key.
Create site Counts against the plan and issues the tracking key.
Update site Changes the domain the tracker is bound to.
Rotate site key Breaks every installed snippet.
Update tracking options Changes what the tracker collects on the live website.
Update ad attribution Changes what the tracker reads on the live website and whether orders keep a customer key: a choice made in the dashboard.
Reset site data, Delete site Destroys data.
Get site settings extras, Get visitor settings Settings screen helper.
Set preset goal Switching a preset on changes what the tracker sends.
Update revenue settings, Save attribution choice, Remove exclusion, Set revenue excluded paths A site setting, changed in the dashboard.
Update workspace A workspace setting, changed in the dashboard.
Delete workspace Destroys everything the workspace holds.
Get billing summary Per-person preference inside; plan facts reach tokens through usage.get.
Choose plan, Cancel plan Changes the plan. Billing is done in the dashboard.
List exclusions Can hold the team's IP addresses.
Add exclusion Drops hits for good.
Get notification settings, Save notification settings Holds email addresses.
Get sharing Returns the dashboard share token.
Enable share link, Enable embed Issues a public token.
Save share link, Regenerate share link, Revoke share link, Save embed Changes a public share link or widget.
Regenerate embed, Disable embed Breaks widgets already placed.
List site team, Invite viewer, Resend invite, Revoke invite, Remove viewer, List members, List workspace invitations, Invite admin, Change member role, Remove member Lists or changes the people of the workspace.
Leave site, Leave workspace, Accept invite About the signed-in person, and a token is not one.
List api tokens, Create api token, Revoke api token, List audit log Tokens manage tokens only from the dashboard.
Update profile, Request email change, Change password, List sessions, Revoke session, Delete account Belongs to the signed-in person's own account.
Get export estimate Belongs with the CSV download, which is a file.
Update visitor settings Sets a cookie on the live website and decides how consent is read: a choice with legal weight, made in the dashboard.
Find visitor by cookie Takes a cookie value a visitor sent in a request; never through a token.
Delete visitor, Delete all visitors Destroys data; tokens never delete.
Connect shopify Opens the address that writes a store's orders to the site.
Set shopify secret Saves or replaces the store secret that signs deliveries.
Disconnect shopify Closes the address that receives orders.
Delete cost line Destroys a cost line; profit changes for every past period.
Delete product cost Destroys a product cost.

Limits #

  • 120 requests per minute per workspace, over all its tokens, counted approximately and per Cloudflare location. Over the limit the answer is 429 with Retry-After: 60.
  • 30 attempts per minute from one address with tokens that are not recognised.
  • A body of at most 65,536 bytes.
  • Lists: limit 1 to 100, offset 0 to 1,000, and offset plus limit at most 1,000. A cursor is the nextCursor of the page before, sent back unchanged.
  • No CORS headers are sent. The API is for programs, not for pages in a browser.

Filters #

Reports about one site take a filters object such as { "country": "us", "path.has": "pricing" }. A plain key means "is", a key ending in .not means "is not" and a key ending in .has means "contains". Filters are joined with AND. At most 10 keys, of which at most 3 may end in .has. A key that is not in this table is refused.

Key Meaning
path Page path is this value, for example /pricing. Applies to single page views, not to whole visits.
path.not Page is not this value. Rows that have no value are kept.
path.has Page contains this text, ignoring case. 1 to 100 characters.
entry The first page of the visit is this path.
entry.not Entry page is not this value. Rows that have no value are kept.
entry.has Entry page contains this text, ignoring case. 1 to 100 characters.
exit The last page of the visit is this path.
exit.not Exit page is not this value. Rows that have no value are kept.
exit.has Exit page contains this text, ignoring case. 1 to 100 characters.
hostname The hostname the page was served from is this value, for example blog.example.com.
hostname.not Hostname is not this value. Rows that have no value are kept.
hostname.has Hostname contains this text, ignoring case. 1 to 100 characters.
ref The referring site is this host, for example news.ycombinator.com.
ref.not Referrer is not this value. Rows that have no value are kept.
ref.has Referrer contains this text, ignoring case. 1 to 100 characters.
channel The traffic channel is this one: direct, organic_search, organic_social, referral, ai, email, paid or campaign.
channel.not Channel is not this value. Rows that have no value are kept.
ai The visit came from this AI tool, by its key, for example chatgpt.
ai.not AI tool is not this value. Rows that have no value are kept.
country Two-letter country code in lower case, for example us.
country.not Country is not this value. Rows that have no value are kept.
region ISO 3166-2 region code, for example US-CA. Needs country; ignored without it.
region.not Region is not this value. Rows that have no value are kept.
city City name as shown in the locations breakdown. Needs country; ignored without it.
city.not City is not this value. Rows that have no value are kept.
city.has City contains this text, ignoring case. 1 to 100 characters.
browser Browser name, for example Chrome.
browser.not Browser is not this value. Rows that have no value are kept.
browser.has Browser contains this text, ignoring case. 1 to 100 characters.
os Operating system name, for example iOS.
os.not OS is not this value. Rows that have no value are kept.
os.has OS contains this text, ignoring case. 1 to 100 characters.
device Device class: desktop, mobile or tablet.
device.not Device is not this value. Rows that have no value are kept.
utm_source The utm_source tag of the visit.
utm_source.not Source is not this value. Rows that have no value are kept.
utm_source.has Source contains this text, ignoring case. 1 to 100 characters.
utm_medium The utm_medium tag of the visit.
utm_medium.not Medium is not this value. Rows that have no value are kept.
utm_medium.has Medium contains this text, ignoring case. 1 to 100 characters.
utm_campaign The utm_campaign tag of the visit.
utm_campaign.not Campaign is not this value. Rows that have no value are kept.
utm_campaign.has Campaign contains this text, ignoring case. 1 to 100 characters.
utm_term The utm_term tag of the visit.
utm_term.not Term is not this value. Rows that have no value are kept.
utm_term.has Term contains this text, ignoring case. 1 to 100 characters.
utm_content The utm_content tag of the visit.
utm_content.not Content is not this value. Rows that have no value are kept.
utm_content.has Content contains this text, ignoring case. 1 to 100 characters.
conversion Only visitors who completed this conversion goal, by the goal's name from goals.list. A name that matches no enabled goal is ignored.
event Only hits of this custom event, by name.
prop Only custom events with this property, written key:value.

Errors #

Every error is { "error": { "code", "message" } }, sometimes with detail, fields or reason. Decide on code, which is stable. message is one sentence that says what to change.

Status Code When Also carries
400 invalid_input The body is not a JSON object, fails the input schema of the operation, or holds a field the operation does not know. fields: each refused field with its path and the reason.
400 invalid A value passed the schema and was then refused by the operation. detail: the field.
400 invalid_cursor A cursor the server did not issue.
401 unauthenticated The Authorization header is missing or malformed, or the token is unknown or revoked, or the person who created it is no longer an Owner or Admin. Header WWW-Authenticate: Bearer.
402 workspace_locked The workspace's dashboards are locked, so reports answer no numbers. reason: limit, grace or expired. The message says what lifts the lock.
403 insufficient_scope An operation that changes something was called with a token that can only read. Header WWW-Authenticate with scope="write".
404 not_found The path is not an operation, the site is not in the workspace of the token, or a row with that id does not exist. detail: what was missing, for a row.
405 method_not_allowed An operation was called with a method other than POST. Header Allow.
409 taken A name or key is already in use. detail: which.
409 limit_reached A cap on how many of something a site or workspace may hold. detail: which.
409 feature_off The operation is about remembered visitors and the site has Remember returning visitors switched off. detail: returning_visitors. The message says where an owner or admin switches it on.
413 payload_too_large The body is larger than 65,536 bytes.
415 unsupported_media_type A body was sent with a content type other than application/json.
422 too_much_data The answer would need more data than one request may read. Narrow the range or add a filter.
429 rate_limited More than 120 requests in a minute for the workspace, or more than 30 tokens in a minute from one address that were not recognised. Header Retry-After: 60.
500 internal Something went wrong on our side.

When the workspace is locked #

The dashboards of a workspace lock when its monthly allowance is used up, and when its trial or plan has ended. While they are locked, every operation that reads a report answers 402 with the code workspace_locked and a reason of limit, grace or expired. The message says what lifts the lock.

Operations that list definitions, such as funnels, goals or saved segments, keep answering, and so do the operations that change them. The page of each read operation says which of the two it does. Plans, usage and limits explains the lock itself.

All operations #

Operation Kind What it does
sites.get Read Site details
sites.list Read List sites
overview.bots Read Filtered bot traffic
overview.breakdown Read Breakdown by dimension
overview.conversionPeak Read Conversions by hour
overview.kpis Read Headline numbers
overview.missingPages Read Pages not found
overview.timeseries Read Traffic over time
events.counts Read Custom event counts
events.insights Read Custom event trends
events.log Read Activity log
events.names Read Custom event names
events.properties Read Custom event properties
realtime.snapshot Read Realtime snapshot
realtime.visitor Read Live visitor
visitors.get Read Remembered visitor
visitors.list Read List remembered visitors
visitors.summary Read Returning visitors summary
funnels.create Write Create funnel
funnels.delete Write Delete funnel
funnels.duplicate Write Duplicate funnel
funnels.list Read List funnels
funnels.report Read Funnel report
funnels.update Write Update funnel
campaigns.breakdown Read Campaign breakdown
campaigns.conversions Read Campaign conversions
campaigns.create Write Create campaign link
campaigns.delete Write Delete campaign link
campaigns.list Read List campaign links
campaigns.totals Read Campaign totals
campaigns.update Write Update campaign link
goals.breakdown Read Conversion rate breakdown
goals.completions Read Goal completions
goals.create Write Create conversion goal
goals.delete Write Delete conversion goal
goals.list Read List conversion goals
goals.update Write Update conversion goal
revenue.kpis Read Revenue totals
revenue.refunds Read Refunds list
revenue.report Read Revenue attribution report
revenue.timeseries Read Revenue over time
performance.report Read Web vitals report
store.attribution Read Which ads earned sales
store.costs Read Store costs
store.createCostLine Write Add a cost line
store.creatives Read Creative report
store.customers Read New customers
store.orders Read Orders and their channels
store.overlap Read Channel overlap
store.profit Read Profit report
store.reconciliation Read Revenue reconciliation
store.saveCostSettings Write Save cost rules
store.setProductCosts Write Set product costs
store.summary Read Store summary
store.updateCostLine Write Change a cost line
store.uploadProductCosts Write Upload product costs
store.uploadSpend Write Upload ad spend
notes.create Write Create chart note
notes.delete Write Delete chart note
notes.list Read List chart notes
notes.update Write Update chart note
segments.create Write Save a segment
segments.delete Write Delete a segment
segments.list Read List saved segments
segments.update Write Update a segment
alerts.create Write Create alert rule
alerts.delete Write Delete alert rule
alerts.deliveries Read List alert deliveries
alerts.list Read List alert rules
alerts.test Write Send test delivery
alerts.update Write Update alert rule
embeds.get Read Embed widgets
workspace.get Read Workspace details
workspace.live Read Visitors online now
workspace.summary Read All sites summary
usage.get Read Usage this month
connections.list Read Ad platform connections