Skip to main content

LENS API Endpoints

Access LENS features programmatically via the REST API.

LENS exposes three groups of endpoints:

  • Insights (/lens/insights/*) — AI-generated insights (anomalies, opportunities, trends, alerts, health), plus per-insight actions.
  • Settings & usage (/lens/settings, /lens/chat/usage) — notification configuration and chat usage.
  • Reports (/lens/reports/*) — structured weekly/monthly executive reports.
  • AI Assistant (/assistant/*) — conversational chat over your analytics data.

Authentication

All LENS endpoints require authentication via Bearer token:

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
https://my.sealmetrics.com/api/v1/lens/insights?account_id=YOUR_ACCOUNT_ID

See Authentication for details on obtaining tokens.

All paths below are relative to the API base URL https://my.sealmetrics.com/api/v1.

Most endpoints require an account_id query parameter and verify that the authenticated user has access to that account. Write actions (mark read, dismiss, submit feedback, update settings, generate reports, delete conversations) additionally require a token with the write scope.

Endpoints Overview

Insights

EndpointMethodDescription
/lens/insightsGETList insights (paginated, filterable)
/lens/insights/summaryGETCounts by severity / read status
/lens/insights/groupedGETInsights grouped by a common attribute
/lens/insights/{insight_id}GETGet a single insight
/lens/insights/{insight_id}/readPATCHMark insight as read
/lens/insights/{insight_id}/unreadPATCHMark insight as unread
/lens/insights/{insight_id}/dismissPATCHDismiss an insight
/lens/insights/{insight_id}/feedbackPOSTSubmit feedback on an insight
/lens/insights/{insight_id}/send-emailPOSTEmail an insight report

Settings & usage

EndpointMethodDescription
/lens/settingsGETGet LENS notification settings
/lens/settingsPATCHUpdate LENS notification settings
/lens/chat/usageGETGet chat question usage
/lens/chat/usage/incrementPOSTIncrement chat usage counter

Reports

EndpointMethodDescription
/lens/reportsGETList generated reports
/lens/reports/{report_id}GETGet a report
/lens/reports/generatePOSTGenerate a report
/lens/reports/latest/{report_type}GETGet latest weekly/monthly report

AI Assistant

EndpointMethodDescription
/assistant/chatPOSTSend a message to the AI assistant
/assistant/sessionsGETList recent chat sessions
/assistant/conversations/{id}GETGet conversation history
/assistant/conversations/{id}DELETEDelete a conversation
/assistant/toolsGETList tools available to the assistant

Insights

Insights are the AI-generated findings produced by LENS.

Insight object

FieldTypeDescription
idstring (UUID)Insight ID
account_idstringAccount the insight belongs to
insight_typestringOne of anomaly, opportunity, trend, alert, health (additional internal types may also appear)
severitystringgreen, yellow, or red
categorystring | nullRule category derived from source_rule
titlestringShort title
descriptionstring | nullDetailed description
recommendationstring | nullRecommended action
economic_impactnumber | nullEstimated economic impact
source_toolstring | nullTool that produced the insight
source_rulestring | nullDetection rule identifier
related_entitystring | nullAffected entity (e.g. channel, page)
deep_linkstring | nullLink into the dashboard
metadataobjectAdditional structured data
created_atstring (ISO 8601)Creation timestamp
expires_atstring | nullExpiration timestamp
read_atstring | nullWhen the current user read it
dismissed_atstring | nullWhen it was dismissed
is_readbooleanWhether the current user has read it
is_dismissedbooleanWhether it is dismissed
is_lockedbooleanWhether the insight is locked behind a higher tier
locked_tierstring | nullTier required to unlock, if locked
evidenceobject | nullStatistical basis for the insight
user_feedbackstring | nullCurrent user's feedback, if any

List insights

GET /lens/insights

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID
insight_typestring (repeatable)NoFilter by type: anomaly, opportunity, trend, alert, health
severitystring (repeatable)NoFilter by severity: green, yellow, red
unreadbooleanNoOnly return unread insights (default false)
include_dismissedbooleanNoInclude dismissed insights (default false)
pageintegerNoPage number (≥ 1, default 1)
page_sizeintegerNoItems per page (1–100, default 50)

Response

{
"insights": [
{
"id": "3f8b9c2e-1a4d-4c7e-9f2a-1b2c3d4e5f6a",
"account_id": "acc_123456",
"insight_type": "anomaly",
"severity": "red",
"category": "conversions",
"title": "Conversion rate dropped sharply",
"description": "Conversion rate fell 35% versus the prior period.",
"recommendation": "Review mobile checkout performance.",
"economic_impact": 1240.50,
"source_tool": "stats",
"source_rule": "conversion_rate_drop",
"related_entity": "mobile",
"deep_link": "/lens/report/3f8b9c2e-1a4d-4c7e-9f2a-1b2c3d4e5f6a",
"metadata": {},
"created_at": "2024-01-15T14:32:00Z",
"expires_at": null,
"read_at": null,
"dismissed_at": null,
"is_read": false,
"is_dismissed": false,
"is_locked": false,
"locked_tier": null,
"evidence": null,
"user_feedback": null
}
],
"total": 23,
"page": 1,
"page_size": 50,
"total_pages": 1,
"has_next": false,
"has_prev": false
}

Example

curl "https://my.sealmetrics.com/api/v1/lens/insights?account_id=acc_123456&severity=red&unread=true" \
-H "Authorization: Bearer YOUR_TOKEN"

Get insights summary

Returns counts useful for notification badges.

GET /lens/insights/summary

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID

Response

{
"total_count": 23,
"unread_count": 5,
"red_count": 2,
"yellow_count": 9,
"green_count": 12,
"has_critical": true
}

List grouped insights

Groups similar insights to reduce noise.

GET /lens/insights/grouped

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID
group_bystringNosource_rule (default), insight_type, or related_entity
include_dismissedbooleanNoInclude dismissed insights (default false)

Response

{
"groups": [
{
"group_key": "conversion_rate_drop",
"group_title": "Conversion Rate Drop",
"insight_type": "anomaly",
"max_severity": "red",
"insight_count": 4,
"unread_count": 2,
"total_economic_impact": 4820.00,
"latest_insight": { "id": "3f8b9c2e-1a4d-4c7e-9f2a-1b2c3d4e5f6a", "...": "full Insight object" },
"related_entities": ["mobile", "google_ads"],
"first_detected_at": "2024-01-10T08:00:00Z",
"last_detected_at": "2024-01-15T14:32:00Z"
}
],
"total_groups": 1
}

latest_insight is a full Insight object (see Insight object).

Get insight

GET /lens/insights/{insight_id}

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID

Returns a single Insight object, or 404 if not found.

Mark insight as read / unread

PATCH /lens/insights/{insight_id}/read
PATCH /lens/insights/{insight_id}/unread

Requires the write scope. Pass account_id as a query parameter. Returns the updated Insight object.

curl -X PATCH \
"https://my.sealmetrics.com/api/v1/lens/insights/3f8b9c2e-1a4d-4c7e-9f2a-1b2c3d4e5f6a/read?account_id=acc_123456" \
-H "Authorization: Bearer YOUR_TOKEN"

Dismiss insight

Dismissed insights do not appear in the default list view.

PATCH /lens/insights/{insight_id}/dismiss

Requires the write scope. Pass account_id as a query parameter. Returns the updated Insight object.

Submit feedback

POST /lens/insights/{insight_id}/feedback

Requires the write scope. Pass account_id as a query parameter.

Request Body

{
"feedback_type": "helpful",
"comment": "Spotted a real issue we hadn't noticed."
}
FieldTypeRequiredDescription
feedback_typestringYesOne of helpful, not_helpful, incorrect, already_known
commentstringNoOptional free-text comment

Response

Returns 201 Created:

{
"status": "ok",
"feedback_id": 42,
"feedback_type": "helpful",
"comment": "Spotted a real issue we hadn't noticed.",
"created_at": "2024-01-15T16:00:00Z"
}

Send insight report via email

Emails a formatted version of an insight to one or more recipients. This is a user-triggered action and bypasses the account's notification settings.

POST /lens/insights/{insight_id}/send-email

Pass account_id as a query parameter.

Request Body

{
"recipients": ["teammate@company.com"],
"message": "Take a look at this before our meeting."
}
FieldTypeRequiredDescription
recipientsarray of stringYes1–10 recipient email addresses
messagestringNoOptional note prepended to the email

Response

{
"status": "ok",
"sent_count": 1,
"failed_count": 0,
"recipients": ["teammate@company.com"]
}

Settings

Get LENS settings

GET /lens/settings

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID

Response

{
"account_id": "acc_123456",
"is_enabled": true,
"notify_email": true,
"notify_on_red": true,
"notify_on_yellow": false,
"notify_on_green": false,
"email_recipients": ["alerts@company.com"],
"analysis_frequency": "daily",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-15T00:00:00Z"
}

Update LENS settings

PATCH /lens/settings

Requires the write scope. Pass account_id as a query parameter. All fields are optional; only provided fields are updated.

Request Body

{
"notify_on_yellow": true,
"email_recipients": ["alerts@company.com", "ops@company.com"],
"analysis_frequency": "weekly"
}
FieldTypeDescription
is_enabledbooleanEnable/disable LENS for the account
notify_emailbooleanSend email notifications
notify_on_redbooleanNotify on critical (red) insights
notify_on_yellowbooleanNotify on warning (yellow) insights
notify_on_greenbooleanNotify on positive (green) insights
email_recipientsarray of stringRecipient email addresses
analysis_frequencystringdaily, weekly, or manual

Returns the updated settings object.


Chat usage

LENS uses a Bring-Your-Own-Key (BYOK) model for the AI assistant, so chat usage is effectively unlimited. These endpoints exist for compatibility with usage UIs and report very high limits.

Get chat question usage

GET /lens/chat/usage

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID

Response

{
"questions_used": 0,
"questions_limit": 999999,
"bonus_questions": 0,
"questions_remaining": 999999,
"period_start": "2024-01-01T00:00:00Z",
"period_end": "2024-01-15T00:00:00Z",
"percentage_used": 0
}

Increment chat usage

POST /lens/chat/usage/increment

Requires the write scope. Pass account_id as a query parameter. Under the BYOK model this always allows the question.

Response

{
"can_ask": true,
"questions_remaining": 999999,
"message": null
}

AI Assistant

The AI assistant is a conversational interface over your analytics data. It is served under /assistant (not /lens).

Assistant endpoints are unavailable while impersonating another user.

Send a message

POST /assistant/chat

Request Body

{
"message": "Why did conversions drop last week?",
"account_id": "acc_123456",
"conversation_id": "conv_abc123",
"language": "en"
}
FieldTypeRequiredDescription
messagestringYesUser message (1–1000 characters)
account_idstringYesAccount to query data for
conversation_idstringNoContinue an existing conversation
languagestringNoResponse language: es (default) or en
providerstringNoLLM provider to use (e.g. anthropic, openai). Uses the account default if omitted

Response

Responses are wrapped in the standard API envelope. The data object contains the assistant reply plus optional structured charts and tables the frontend can render.

{
"data": {
"response": "Conversions dropped 23% last week, driven mainly by a decline in Google Ads traffic and a lower mobile conversion rate.",
"conversation_id": "conv_abc123",
"tools_used": [
{ "tool_name": "get_stats", "success": true, "duration_ms": 412 }
],
"charts": [
{
"type": "line",
"title": "Conversions by day",
"data": [
{ "date": "2024-01-08", "value": 156 },
{ "date": "2024-01-15", "value": 120 }
],
"x_key": "date",
"y_key": "value",
"y_label": "Conversions"
}
],
"tables": [
{
"title": "Top sources",
"columns": ["Source", "Conversions"],
"rows": [["Google Ads", 78], ["Organic", 42]]
}
],
"input_tokens": 1820,
"output_tokens": 540
}
}
FieldTypeDescription
responsestringAssistant's reply
conversation_idstringConversation ID for follow-ups
tools_usedarrayTools invoked: { tool_name, success, duration_ms }
chartsarrayChart objects: type (line/bar/pie), title, data, x_key, y_key, y_label
tablesarrayTable objects: title, columns, rows
input_tokensintegerInput tokens consumed
output_tokensintegerOutput tokens generated

Follow-up suggestions are not returned by this endpoint. Use conversation_id to continue a conversation.

Errors

StatusCondition
403No access to the account or to the conversation
401Provider authentication failed (invalid API key)
409No LLM provider/API key configured (detail.error_code indicates the cause)
429Provider rate limit reached (includes a Retry-After header)

Example

curl -X POST https://my.sealmetrics.com/api/v1/assistant/chat \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "What were my top traffic sources last week?",
"account_id": "acc_123456",
"language": "en"
}'

List recent sessions

GET /assistant/sessions

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID
limitintegerNoMax sessions to return (1–50, default 10)

Response

{
"data": {
"sessions": [
{
"id": "conv_abc123",
"title": "Conversion drop analysis",
"message_count": 6,
"created_at": "2024-01-15T14:00:00Z",
"updated_at": "2024-01-15T14:30:00Z",
"is_active": true
}
],
"total": 1
}
}

Get conversation history

GET /assistant/conversations/{conversation_id}

Response

{
"data": {
"conversation_id": "conv_abc123",
"account_id": "acc_123456",
"title": "Conversion drop analysis",
"messages": [
{
"role": "user",
"content": "Why did conversions drop last week?",
"timestamp": "2024-01-15T14:00:00Z",
"charts": [],
"tables": []
},
{
"role": "assistant",
"content": "Conversions dropped 23% last week...",
"timestamp": "2024-01-15T14:00:05Z",
"charts": [],
"tables": []
}
],
"created_at": "2024-01-15T14:00:00Z",
"updated_at": "2024-01-15T14:30:00Z"
}
}

Returns 404 if the conversation does not exist.

Delete a conversation

DELETE /assistant/conversations/{conversation_id}

Requires the write scope.

Response

{
"data": { "deleted": true }
}

List available tools

GET /assistant/tools

Response

{
"data": {
"tools": [
{
"name": "get_stats",
"description": "Retrieve aggregated analytics metrics.",
"category": "analytics"
}
],
"total": 1
}
}

Reports

Structured executive reports (weekly or monthly). Served under /lens/reports.

List reports

GET /lens/reports

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID
report_typestringNoFilter by weekly or monthly
pageintegerNoPage number (≥ 1, default 1)
page_sizeintegerNoItems per page (1–50, default 12)

Response

{
"reports": [
{
"id": "9a1c2b3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"report_type": "weekly",
"period_start": "2024-01-08",
"period_end": "2024-01-14",
"period_label": "Jan 8–14, 2024",
"status": "ready",
"created_at": "2024-01-15T06:00:00Z",
"view_count": 3,
"revenue": 18250.00,
"revenue_change": 4.2,
"conversions": 142,
"insight_count": 7
}
],
"total": 1,
"page": 1,
"page_size": 12
}

Get report

Fetching a report marks it as viewed.

GET /lens/reports/{report_id}

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID

Returns a full report object including executive_summary, key_takeaways, key_metrics, channel_performance, funnel_health, audience_insights, top_insights, and action_items. Returns 404 if not found.

Generate report

POST /lens/reports/generate

Requires the write scope. Pass account_id as a query parameter.

Request Body

{
"report_type": "weekly",
"period_end": "2024-01-14"
}
FieldTypeRequiredDescription
report_typestringYesweekly or monthly
period_endstringNoEnd of period (YYYY-MM-DD). Defaults to the last completed period

Returns 201 Created with the full report object. If a ready report for the same period already exists, it is returned instead.

Get latest report

GET /lens/reports/latest/{report_type}

report_type must be weekly or monthly.

Query Parameters

ParameterTypeRequiredDescription
account_idstringYesAccount ID

Returns the most recent ready report of the given type, or 404 if none exists.


Error Responses

LENS endpoints use standard HTTP status codes. Common cases:

StatusMeaning
400Invalid request (e.g. malformed period_end, invalid email)
401Missing/invalid token, or provider auth failure (assistant)
403No access to the account, or LENS not available on the free plan
404Resource not found
409No LLM provider configured (assistant chat)
429Rate limit reached (assistant chat — includes Retry-After)

LENS is not available on the free plan; insight endpoints return 403 for accounts on that tier.