Skip to content
SSalesShiftDocs
API reference

Reports and analytics

Report datasets, ad-hoc and saved reports, dashboards, schedules, attribution, goals and forecast, plus sales, email and funnel analytics.

36 endpoints· 16 called live· 20 not exercised here· verified against http://127.0.0.1:8741

36 endpoints

GET/api/v1/salesshift/analytics/activity/healthNot exercised hereIs the projection actually keeping up, and what is it missing?

Is the projection actually keeping up, and what is it missing? Three independent views, because they fail independently: what this process published (producer counters), what the broker says the group has committed (lag), and what actually landed in Postgres. Any of them can be the broken one, and a single aggregated 'healthy' flag would hide which.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/activity/health' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-analytics-activity-healthanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:829Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/activity/timelineNot exercised hereOrdered event history for a contact, a workflow, a run, or the whole org.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Query parameters

NameTypeRequiredNotes
contact_idstring(uuid)?optional
workflow_idstring(uuid)?optional
run_idstring(uuid)?optional
sourcestring?optionalMatches ^(email|workflow)$.
daysintegeroptionalDefault 90. min 1. max 730.
limitintegeroptionalDefault 200. min 1. max 1000.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/activity/timeline' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "stream": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-analytics-activity-timelineanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:760Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/attributionCalled liveCredit won-deal revenue across the touches that preceded it.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
modelstringoptionalDefault "linear".
daysintegeroptionalDefault 180. max 1095.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/attribution' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "model": "str",
    "deals_considered": "int",
    "deals_attributed": "int",
    "channels": [
      "<empty list>"
    ]
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
400model must be one of {...}
#get-api-v1-salesshift-analytics-attributionreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:633Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/analytics/attribution/backfillNot exercised hereBackfill attribution touches for the organization.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/analytics/attribution/backfill' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "success": "…",
  "touches_created": "…"
}
Top-level keys read from the handler's return statements.
#post-api-v1-salesshift-analytics-attribution-backfillreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:736Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/campaign-performanceNot exercised herePer-campaign engagement: opened/replied come from ss_email_tracking.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
daysintegeroptionalDefault 30.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/campaign-performance' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-analytics-campaign-performanceanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:591Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/contract-cycleNot exercised hereE-sign cycle: status counts, avg hours sent→completed, last 5 contracts.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/contract-cycle' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-analytics-contract-cycleanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:640Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/emailCalled liveSent/opened/clicked/replied/bounced counts from the email tracking table.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/email' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "totals": {
      "sent": "int",
      "opened": "int",
      "clicked": "int",
      "replied": "int",
      "bounced": "int",
      "failed": "int",
      "unsubscribed": "int"
    },
    "rates": {
      "open_rate": "float",
      "click_rate": "float",
      "reply_rate": "float",
      "bounce_rate": "float"
    },
    "per_sequence": [
      {
        "sequence": "...",
        "sent": "...",
        "opened": "...",
        "replied": "..."
      },
      "...x4"
    ]
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-analytics-emailanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:128Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/salesshift/analytics/engagementNot exercised hereReply-category breakdown + top 10 engaged contacts (opens + 5x replies).
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
daysintegeroptionalDefault 30. min 1. max 365.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/engagement' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-analytics-engagementanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:538Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/funnelNot exercised hereDeal pipeline funnel: stages in display_order with OPEN deal count, value and each stage's share of the first stage (deals sit in their CURRENT stage).

Deal pipeline funnel: stages in display_order with OPEN deal count, value and each stage's share of the first stage (deals sit in their CURRENT stage). The status filter matches the Overview aggregate above — without it the same stage reported a different count on /analytics than on /overview, because won and lost deals kept their stage_id.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/funnel' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-analytics-funnelanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:491Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/overviewCalled liveONE aggregate powering the Overview dashboard — every number is real SQL.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
daysintegeroptionalDefault 30. min 1. max 365.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/overview' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "days": "int",
    "contacts": {
      "total": "int",
      "new_30d": "int"
    },
    "companies": {
      "total": "int"
    },
    "deals": {
      "open_count": "int",
      "open_value": "float",
      "won_value_30d": "float",
      "stages": [
        "...",
        "...x6"
      ]
    },
    "emails": {
      "sent_30d": "int",
      "opened_30d": "int",
      "replied_30d": "int",
      "open_rate": "float",
      "reply_rate": "float"
    },
    "sequences": {
      "active": "int",
      "enrolled": "int"
    },
    "campaigns": {
      "total": "int",
      "sending": "int",
      "done": "int",
      "last": {
        "id": "...",
        "name": "...",
        "status": "...",
        "sent": "...",
        "opened": "..."
      }
    },
    "meetings": {
      "upcoming_7d": "int"
    },
    "contracts": {
      "draft": "int",
      "sent": "int",
      "partially_signed": "int",
      "completed": "int",
      "voided": "int"
    },
    "opportunities": {
      "open": "int",
      "applications": "int"
    },
    "mailboxes": {
      "count": "int"
    },
    "unread_notifications": "int",
    "recent_activity": [
      {
        "title": "...",
        "message": "...",
        "created_at": "...",
        "data": "..."
      },
      "...x10"
    ]
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-analytics-overviewanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:248Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/salesshift/analytics/pipeline-historyCalled liveWhat the funnel looked like over time — the question fixed dashboards could never answer.

What the funnel looked like over time — the question fixed dashboards could never answer.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
daysintegeroptionalDefault 90. max 730.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/pipeline-history' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "date": "str",
      "stage": "str",
      "deal_count": "int",
      "amount_cents": "int",
      "weighted_cents": "int"
    },
    "...x9"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-analytics-pipeline-historyreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:554Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/analytics/pipeline-snapshot/runNot exercised hereTake a pipeline snapshot immediately instead of waiting for the scheduled run.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/analytics/pipeline-snapshot/run' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "rows_written": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#post-api-v1-salesshift-analytics-pipeline-snapshot-runreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:579Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/analytics/salesCalled liveWin/loss counts and pipeline value aggregated from the org's deals.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/sales' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "win_rate": "float",
    "deals": {
      "open": "int",
      "won": "int",
      "lost": "int"
    },
    "won_value": "float",
    "avg_deal_size": "float",
    "per_stage": [
      {
        "stage": "...",
        "color": "...",
        "count": "...",
        "value": "..."
      },
      "...x6"
    ],
    "velocity": [
      {
        "stage": "...",
        "avg_hours": "...",
        "transitions": "..."
      },
      "...x1"
    ],
    "contacts_monthly": [
      {
        "month": "...",
        "count": "..."
      },
      "...x1"
    ]
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-analytics-salesanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:30Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/salesshift/analytics/timeseriesNot exercised herePer-day sent/opened/replied counts.

Per-day sent/opened/replied counts. LEFT JOIN against generate_series so zero-days appear. Raw SQL: to_char lives in the projection only, so the asyncpg bind-param-in-GROUP-BY gotcha does not apply.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
daysintegeroptionalDefault 30. min 1. max 365.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/analytics/timeseries' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-analytics-timeseriesanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:427Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/dashboardsCalled liveThe organization's dashboards.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/dashboards' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "id": "str",
      "name": "str",
      "description": "null",
      "is_default": "bool",
      "visibility": "str"
    },
    "...x1"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-dashboardsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:258Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/dashboardsNot exercised hereCreate a dashboard owned by the calling user.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+data

Request body (required) — DashboardIn

FieldTypeRequiredNotes
namestringrequired
descriptionstring?optional
is_defaultbooleanoptionalDefault false.

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/dashboards' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "name": "<string>", "description": "<string>", "is_default": false }'

Response · 201

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#post-api-v1-salesshift-dashboardsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:274Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/dashboards/{dashboard_id}Not exercised hereOne dashboard with its widgets.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Path parameters

NameTypeRequiredNotes
dashboard_idstring(uuid)required

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/dashboards/{dashboard_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Dashboard not found
#get-api-v1-salesshift-dashboards-dashboard-idreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:288Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
POST/api/v1/salesshift/dashboards/{dashboard_id}/widgetsNot exercised hereAdd a widget backed by a saved report to a dashboard.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+data

Path parameters

NameTypeRequiredNotes
dashboard_idstring(uuid)required

Request body (required) — WidgetIn

FieldTypeRequiredNotes
report_idstring(uuid)required
title_overridestring?optional
xintegeroptionalDefault 0.
yintegeroptionalDefault 0.
wintegeroptionalDefault 6.
hintegeroptionalDefault 4.

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/dashboards/{dashboard_id}/widgets' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "report_id": "<string(uuid)>", "title_override": "<string>", "x": 0, "y": 0, "w": 6, "h": 4 }'

Response · 201

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Report not found in this workspace
#post-api-v1-salesshift-dashboards-dashboard-id-widgetsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:330Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
DELETE/api/v1/salesshift/dashboards/widgets/{widget_id}Not exercised hereRemove a widget from a dashboard.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
widget_idstring(uuid)required

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/dashboards/widgets/{widget_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "deleted": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#delete-api-v1-salesshift-dashboards-widgets-widget-idreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:351Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
PATCH/api/v1/salesshift/deals/{deal_id}/forecast-categoryNot exercised hereSet a deal's forecast category (commit, best case, pipeline, omitted).
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
deal_idstring(uuid)required

Request body (required)

Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.

forecast_category

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X PATCH 'https://api.vxcloud.io/api/v1/salesshift/deals/{deal_id}/forecast-category' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "forecast_category": "<value>" }'

Response · 200

Top-level keys
{
  "forecast_category": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400forecast_category must be one of {...}
404Deal not found
#patch-api-v1-salesshift-deals-deal-id-forecast-categoryreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:940Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/emailsCalled liveInbox feed — every tracked outbound email with its engagement state.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
statusstring?optional
limitintegeroptionalDefault 50. min 1. max 200.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/emails' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "id": "str",
      "to_email": "str",
      "from_email": "str",
      "contact_id": "str",
      "contact_name": "str",
      "subject": "str",
      "status": "str",
      "provider": "str",
      "open_count": "int",
      "click_count": "int",
      "error": "str",
      "body_html": "str",
      "reply_body": "null",
      "reply_category": "null",
      "sent_at": "null",
      "first_opened_at": "null",
      "replied_at": "null",
      "created_at": "str"
    },
    "...x2"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-emailsanalytics_router · vxcloud_fastapiclient/app/services/salesshift/analytics_router.py:184Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/salesshift/forecastCalled liveCategory roll-up from live deals, plus every submission for the period so called-vs-actual is visible rather than lost.

Category roll-up from live deals, plus every submission for the period so called-vs-actual is visible rather than lost.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
period_startstring?optional
period_endstring?optional

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/forecast' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "period_start": "str",
    "period_end": "str",
    "categories": {
      "best_case": {
        "deal_count": "...",
        "amount_cents": "..."
      },
      "commit": {
        "deal_count": "...",
        "amount_cents": "..."
      },
      "pipeline": {
        "deal_count": "...",
        "amount_cents": "..."
      }
    },
    "closed_won_cents": "int",
    "submissions": [
      {
        "id": "...",
        "user_id": "...",
        "commit_cents": "...",
        "best_case_cents": "...",
        "pipeline_cents": "...",
        "note": "...",
        "submitted_at": "..."
      },
      "...x1"
    ]
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-forecastreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:885Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/forecast/submitNot exercised hereAppend a submission.

Append a submission. Never an upsert — comparing what a rep called in week 2 against what actually closed is the whole point.

Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+data

Request body (required)

Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.

best_case_centscommit_centscurrencynoteperiod_endperiod_startpipeline_cents

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/forecast/submit' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "best_case_cents": "<value>", "commit_cents": "<value>", "currency": "<value>", "note": "<value>", "period_end": "<value>", "period_start": "<value>", "pipeline_cents": "<value>" }'

Response · 201

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#post-api-v1-salesshift-forecast-submitreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:861Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/goalsCalled liveThe organization's goals.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/goals' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "id": "str",
      "subject_type": "str",
      "subject_id": "str",
      "metric": "str",
      "period": "str",
      "period_start": "str",
      "period_end": "str",
      "target_value": "int",
      "currency": "null"
    },
    "...x1"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-goalsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:753Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/goalsNot exercised hereCreate a goal against a known metric.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+data

Request body (required)

Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.

currencymetricperiodperiod_endperiod_startsubject_idsubject_typetarget_value

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/goals' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "currency": "<value>", "metric": "<value>", "period": "<value>", "period_end": "<value>", "period_start": "<value>", "subject_id": "<value>", "subject_type": "<value>", "target_value": "<value>" }'

Response · 201

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400metric must be one of {...}
#post-api-v1-salesshift-goalsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:772Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/goals/leaderboardNot exercised hereAttainment per owner: actuals from the same data the reports use, goals from ss_goals, sorted by percentage of target.

Attainment per owner: actuals from the same data the reports use, goals from ss_goals, sorted by percentage of target.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
period_startstring?optional
period_endstring?optional
metricstringoptionalDefault "revenue_won".

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/goals/leaderboard' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-goals-leaderboardreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:798Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/reportsCalled liveThe organization's saved reports.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/reports' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "id": "str",
      "name": "str",
      "description": "null",
      "dataset": "str",
      "config": {
        "measures": "...",
        "dimensions": "..."
      },
      "owner_id": "int",
      "visibility": "str",
      "created_at": "str",
      "updated_at": "str"
    },
    "...x1"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-reportsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:120Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/reportsCalled liveSave a report; the definition is compiled and run first, so an unrunnable report is never stored.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+data

Request body (required) — ReportIn

FieldTypeRequiredNotes
namestringrequired
descriptionstring?optional
datasetstringrequired
configobjectoptional
visibilitystringoptionalDefault "org".

The body in the request below is the exact one sent during verification.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/reports' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "name": "Contacts by lifecycle stage", "dataset": "contacts", "config": { "dimensions": [ { "field": "contact.lifecycle_stage" } ], "measures": [ { "field": "contact.id", "agg": "count" } ] } }'

Response · 201

Observed shape
{
  "success": "bool",
  "data": {
    "id": "str",
    "name": "str",
    "dataset": "str",
    "config": {
      "dimensions": "...",
      "measures": "..."
    }
  }
}
Observed on 2026-08-07 — keys are real, values are the types that came back.

Errors

Statusdetail
400computed at runtime: str(exc)
400Add at least one measure
400Each dimension must be an object
400Unknown dataset '<key>'. Available: campaigns, contacts, deals, email_activity, invoices, mrr_movements, payments, quotes, subscriptions, tasks
#post-api-v1-salesshift-reportsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:132Called against http://127.0.0.1:8741 on 2026-08-07 with a real JWT while the documentation was being revised; the response matched the shape recorded below.
GET/api/v1/salesshift/reports/{report_id}Called liveOne saved report, executed by default.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Path parameters

NameTypeRequiredNotes
report_idstring(uuid)required

Query parameters

NameTypeRequiredNotes
runbooleanoptionalDefault true.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/reports/{report_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "id": "str",
    "name": "str",
    "description": "null",
    "dataset": "str",
    "config": {
      "measures": [
        "...",
        "...x1"
      ],
      "dimensions": [
        "...",
        "...x1"
      ]
    },
    "owner_id": "int",
    "visibility": "str",
    "created_at": "str",
    "updated_at": "str",
    "result": {
      "dataset": "str",
      "columns": [
        "...",
        "...x2"
      ],
      "rows": [
        "...",
        "...x6"
      ],
      "row_count": "int",
      "truncated": "bool"
    }
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
404Report not found
#get-api-v1-salesshift-reports-report-idreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:156Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
PATCH/api/v1/salesshift/reports/{report_id}Not exercised hereUpdate a saved report's name or definition.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Path parameters

NameTypeRequiredNotes
report_idstring(uuid)required

Request body (required)

Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.

configdataset

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X PATCH 'https://api.vxcloud.io/api/v1/salesshift/reports/{report_id}' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "config": "<value>", "dataset": "<value>" }'

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Report not found
400computed at runtime: str(exc)
#patch-api-v1-salesshift-reports-report-idreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:180Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
DELETE/api/v1/salesshift/reports/{report_id}Called liveDelete a report along with its dashboard widgets and schedules.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
report_idstring(uuid)required

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/reports/{report_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "deleted": "bool"
}
Observed on 2026-08-07 — keys are real, values are the types that came back.
#delete-api-v1-salesshift-reports-report-idreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:210Called against http://127.0.0.1:8741 on 2026-08-07 with a real JWT while the documentation was being revised; the response matched the shape recorded below.
GET/api/v1/salesshift/reports/{report_id}/exportCalled liveRun a saved report and return it as a downloadable file.
Auth
get_org_user
Scope
organization
Success
200 · text/csv; charset=utf-8
Envelope
text

Path parameters

NameTypeRequiredNotes
report_idstring(uuid)required

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/reports/{report_id}/export' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
"CSV text: a header row of column labels, then one row per group."
Observed on 2026-08-07 — keys are real, values are the types that came back.

Errors

Statusdetail
404Report not found
400computed at runtime: str(exc)
#get-api-v1-salesshift-reports-report-id-exportreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:229Called against http://127.0.0.1:8741 on 2026-08-07 with a real JWT while the documentation was being revised; the response matched the shape recorded below.
POST/api/v1/salesshift/reports/{report_id}/scheduleNot exercised hereSchedule recurring delivery of a saved report.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+data

Path parameters

NameTypeRequiredNotes
report_idstring(uuid)required

Request body (required) — ScheduleIn

FieldTypeRequiredNotes
frequencystringoptionalDefault "weekly".
hour_utcintegeroptionalDefault 7.
weekdayinteger?optional
day_of_monthinteger?optional
recipientsstringoptionalDefault "".
formatstringoptionalDefault "csv".
is_activebooleanoptionalDefault true.

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/reports/{report_id}/schedule' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "frequency": "weekly", "hour_utc": 7, "weekday": 0, "day_of_month": 0, "recipients": "", "format": "csv", "is_active": true }'

Response · 201

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Report not found
400At least one recipient is required
#post-api-v1-salesshift-reports-report-id-schedulereports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:385Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/reports/{report_id}/schedulesNot exercised hereThe delivery schedules attached to one report.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Path parameters

NameTypeRequiredNotes
report_idstring(uuid)required

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/reports/{report_id}/schedules' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "data": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.
#get-api-v1-salesshift-reports-report-id-schedulesreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:411Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/reports/datasetsCalled liveWhat the builder UI renders.

What the builder UI renders. Adding a dataset server-side is enough — the front end has no hardcoded field list.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/reports/datasets' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "key": "str",
      "label": "str",
      "description": "str",
      "default_date_field": "str",
      "fields": [
        "...",
        "...x16"
      ]
    },
    "...x10"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-reports-datasetsreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:90Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/reports/runCalled liveRun a report definition without saving it.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request body (required)

Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.

configdataset

The body in the request below is the exact one sent during verification.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/reports/run' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "dataset": "contacts", "config": { "metrics": [ { "agg": "count" } ] } }'

Response · 200

Observed shape
{
  "detail": "str"
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
400computed at runtime: str(exc)
#post-api-v1-salesshift-reports-runreports_router · vxcloud_fastapiclient/app/services/salesshift/reports_router.py:101Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.