Sharing and Embed
This reference covers the authenticated and public endpoints used by the sharing system.
Endpoint Groups
| Group | Base |
|---|---|
| Share contexts | /api/v1/share-contexts |
| Dashboard shares | /api/v1/dashboards/:id/shares, /api/v1/dashboard-shares |
| External email auth | /api/v1/share-auth |
| Authenticated external portal | /api/v1/share-portal |
| Public token shares | /api/v1/public/shares/:token |
| Embed generation (authenticated) | /api/v1/embed |
| Embed consumption (public) | /api/embed |
| Sharing audit/analytics | /api/v1/share-events, /api/v1/share-analytics |
1) Share Contexts
All endpoints require internal JWT (Authorization: Bearer <access_token>).
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/share-contexts | List company contexts |
GET | /api/v1/share-contexts/:id | Get a context |
POST | /api/v1/share-contexts | Create context |
PUT | /api/v1/share-contexts/:id | Update context |
PUT | /api/v1/share-contexts/:id/grants | Update context grants |
DELETE | /api/v1/share-contexts/:id | Delete context |
GET | /api/v1/share-contexts/:id/members | List members |
POST | /api/v1/share-contexts/:id/members | Add member (internal_user, group, external_email) |
DELETE | /api/v1/share-contexts/:id/members/:memberId | Remove member |
Example: add external email member
{
"member_type": "external_email",
"email": "customer@company.com"
}
2) Dashboard Shares
These also require internal JWT.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/dashboards/:id/shares | List dashboard shares |
POST | /api/v1/dashboards/:id/shares | Create share (link or embed) |
GET | /api/v1/dashboard-shares | List company shares (paginated) |
PUT | /api/v1/dashboard-shares/:shareId | Update share |
DELETE | /api/v1/dashboard-shares/:shareId | Revoke share |
GET | /api/v1/dashboards/:id/share-filter-candidates | List eligible filters for share policies |
GET | /api/v1/dashboards/:id/embed-parameter-candidates | List eligible embed parameters |
Create payload (POST /api/v1/dashboards/:id/shares)
{
"name": "External customers",
"share_type": "link",
"share_context_id": "65f0f4d7b3f0b902f7f7e123",
"expires_at": "2026-12-31T23:59:59.000Z",
"embed_options": {
"allowed_origins": ["https://portal.customer.com"],
"hide_header": true,
"hide_controls": false
},
"share_filter_policies": [
{
"filter_slug": "status",
"filter_kind": "multi_select",
"mode": "selectable",
"allowed_values": ["Active", "Pending"]
}
]
}
3) External Email Authentication (share-auth)
Public endpoints (no internal JWT).
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/share-auth/request | Request one-time login code |
POST | /api/v1/share-auth/verify | Verify code and receive share_access / share_refresh tokens |
POST | /api/v1/share-auth/refresh | Refresh external tokens |
POST | /api/v1/share-auth/logout | Stateless logout |
Request code
{
"company_slug": "acme",
"email": "customer@company.com"
}
Verify code
{
"company_slug": "acme",
"email": "customer@company.com",
"code": "1234-5678"
}
Verify response
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"access_token_expires_in": 600,
"refresh_token_expires_in": 604800,
"user": {
"id": "...",
"email": "customer@company.com",
"status": "active"
}
}
4) Authenticated External Portal (share-portal)
Requires external token (Authorization: Bearer <share_access_token>).
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/share-portal/contexts | List accessible contexts |
GET | /api/v1/share-portal/:company_slug/contexts | List contexts scoped by company slug |
GET | /api/v1/share-portal/dashboards?context_id=... | List dashboards for a context |
GET | /api/v1/share-portal/:company_slug/dashboards | List dashboards for company (aggregated across contexts) |
GET | /api/v1/share-portal/dashboards/:id?context_id=... | Get dashboard |
GET | /api/v1/share-portal/:company_slug/dashboards/:dashboard_slug?context_id=... | Get dashboard by slug |
GET | /api/v1/share-portal/dashboards/:id/filters/:filter_slug/options?context_id=...&search=... | Resolve filter options |
GET | /api/v1/share-portal/:company_slug/dashboards/:dashboard_slug/filters/:filter_slug/options?context_id=...&search=... | Resolve filter options by slug |
POST | /api/v1/share-portal/dashboards/:id/execute | Execute dashboard |
POST | /api/v1/share-portal/:company_slug/dashboards/:dashboard_slug/execute | Execute dashboard by slug |
Execute body
{
"context_id": "65f0f4d7b3f0b902f7f7e123",
"parameters": {
"status": ["Active"]
}
}
5) Public Token Shares (/api/v1/public)
No authentication required.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/public/shares/:token/resolve | Resolve token and return requires_auth |
GET | /api/v1/public/shares/:token/filters/:filter_slug/options?search=... | Resolve filter options (select/multi_select) |
POST | /api/v1/public/shares/:token/execute | Execute share when requires_auth=false |
Execute body
{
"parameters": {
"period_start": "2025-01-01",
"period_end": "2025-12-31"
}
}
6) Embed
6.1 Embed token/embed URL generation (internal JWT)
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/embed/dashboards/:id | Generate dashboard embed |
POST | /api/v1/embed/visualizations/:id | Generate visualization embed |
Supported body:
{
"fixed_params": { "region": "south" },
"allowed_params": ["seller_id"],
"required_params": ["region"],
"expires_in": 3600
}
6.2 Public stateless embed endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /api/embed/d/:token/info | Dashboard metadata |
GET | /api/embed/d/:token/filters/:filter_slug/options?search=... | Dynamic filter options for embed |
POST | /api/embed/d/:token/execute | Execute dashboard |
GET | /api/embed/v/:token/info | Visualization metadata |
POST | /api/embed/v/:token/execute | Execute visualization |
7) Sharing Audit and Analytics
Internal JWT required.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/share-events | List sharing/auth events |
GET | /api/v1/share-events/:id | Get event details |
GET | /api/v1/share-analytics | Return aggregated analytics |
Dynamic multi_select Filter Options
All 3 modes (public, portal, and embed) expose an options endpoint for select and multi_select filters.
Response:
{
"filter_slug": "status",
"options": [
{ "label": "Active", "value": "Active" }
],
"source": "dynamic"
}
source=static: static options from dashboard config.source=dynamic: options loaded from filter SQL.source=policy: options restricted by share policy.
Frequent Errors
error_code | Where | Meaning |
|---|---|---|
AUTH_REQUIRED | public/shares/:token/* | Share requires external login |
INVALID_CONTEXT_ID | share-portal/* | Missing/invalid context_id |
FILTER_DISABLED_BY_POLICY | */filters/:filter_slug/options | Filter unavailable due to policy |
DB_QUERY_ERROR | */filters/:filter_slug/options | Dynamic options SQL failed |
SHARE_FILTER_POLICY_VIOLATION | share-portal .../execute | Parameters violate share policy |
TOKEN_INVALID | public/embed/portal | Invalid or expired token |