VxCloud
SalesShift — built on VxCloud

SalesShift

A sales product — CRM, outbound sequences, a global prospect pool, quotes, e-signed contracts and invoicing — served by the same control plane, the same credential and the same Vault as everything else in these docs.

This page covers what SalesShift is, how it sits on the platform, the bring-your-own-key model, and exactly how much of it vxcli and the SDKs reach. The per-route reference lives in SalesShift’s own docs app.

1# The credential vxcli already holds works against SalesShift —
2# there is nothing extra to configure.
3vxcli auth login -u your-username -k xc_live_…
4
5# Dashboard counters for your organization
6vxcli salesshift stats
7
8# Search the global prospect pool (addresses come back masked)
9vxcli salesshift leads search --country AU --seniority founder --limit 3
10
11# How many reveals you have left this period
12vxcli salesshift leads quota --output json

One credential, one control plane

SalesShift does not have its own login, its own API key format, or its own base URL. If vxcli auth login worked, these calls work.

salesshift · same credential as the rest of vxcli
bash · Python · TypeScript · Go

What SalesShift is

SalesShift is a sales-execution product: contacts and companies, deal pipelines, multi-step outbound sequences and one-off campaigns, a global prospect pool with metered reveals, a product catalogue that feeds quotes, quotes that freeze into e-signable contracts, invoices with PDFs and recorded payments, recurring subscriptions with an MRR rollup, a calendar with real ICS invitations and working RSVP, plus team messaging and WebRTC calls.

It is not a separate service you deploy. Its routers live inside the same FastAPI control plane that serves the rest of this documentation, under two prefixes:

  • /api/v1/salesshift — 306 operations across 24 router modules.
  • /api/v1/messaging — 57 operations: rooms, messages, guest invites and call metadata.

One piece runs off the control plane: the outbound email worker lives on your tenant node and answers at GET {node}/api/v2/salesshift/email/health — the same node vxcli node current reports.

It runs on the VxCloud platform

Same credential. 281 of the 363 routes resolve the caller through the same dependency the rest of the platform uses, and accept either Authorization: Bearer <jwt> or X-API-Key: xc_live_…. Every query is then filtered by the organization that credential resolves to. There is no separate SalesShift key.

Same tooling. vxcli salesshift is a command group in the same binary; the SDK methods hang off the same client object you use to provision a VM. You do not install anything extra.

Same Vault. Provider credentials go to your workspace Vault namespace — the one described in Store and rotate cloud credentials with Vault. Postgres holds only the metadata row.

Same node. The email worker is a service on your tenant node, so send throughput and rate limiting are governed by hardware you already control.

One thing to know first

The running service is constructed with openapi_url=None, so /openapi.json and /docs return 404 on the API host. Do not point a generator at them — use SalesShift’s own docs app instead.

Bring your own keys

SalesShift sends through providers you connect, not through a platform account you rent capacity from. An organization registers its own mailboxes (IMAP/SMTP, or an OAuth mailbox), its own AI provider and its own enrichment key. You are billed by those providers directly, at their rates.

Payments are the exception. Invoicing is designed around your own Stripe account, but Stripe cannot be connected yet: POST /api/v1/salesshift/settings/integrations answers 400 Unsupported provider: payment/stripe, and Settings → Integrations has no payments group. Invoices, PDFs and manually recorded payments work without it; hosted card checkout does not.

How a key is stored

  • POST /api/v1/salesshift/settings/integrations writes the credential into your workspace Vault and upserts a metadata row — provider, active flag, Vault path, last-tested timestamp. The secret itself never lands in Postgres.
  • POST /api/v1/salesshift/settings/integrations/{id}/test reads the credential back out and uses it against the provider for real. A Vault round-trip on its own proves nothing about whether the key, host, port or password still work.
  • GET /api/v1/salesshift/settings/integrations lists what an organization has connected, by type — email, AI, payment.

BYOK means the feature is only as present as the key. In this deployment the test organization has three integrations and all three are email (imap, smtp, smtp). There is no AI row, which is precisely why the AI-backed endpoints — email drafting, draft rewriting, unread summarisation, call transcription — report a partial or unavailable result rather than a made-up one.

What each surface reaches

The API is the whole product. The CLI and the SDKs are deliberately narrower — they cover email and the leads pool, and nothing else.

REST API/api/v1/salesshift/* and /api/v1/messaging/*

363 operations across 27 router modules — CRM, deals, sequences, campaigns, quotes, contracts, invoices, calendar, deliverability, leads, webmail, messaging and calls.

vxclivxcli salesshift (aliases: ss, sales)Reference

21 commands: tracked email send/list, dashboard stats, the node email worker health check, the leads pool, and saved searches. Nothing else in SalesShift has a command.

SDKsc.salesshift (Python) · .salesshift + .leads (TypeScript) · c.SalesShift() (Go)Reference

20 of the 306 SalesShift routes — the four email/stats calls plus the leads pool. None of the 57 messaging routes.

The CLI has no contact commands. A contact is created by converting a lead — vxcli salesshift leads convert, leads bulk-convert or leads convert-from-pool — because conversion is where consent metadata is written. Nothing else in the CRM is scriptable from the CLI today.

SDK coverage, honestly

Five languages carry a SalesShift surface. All five expose the same two things: the four email/stats calls and the leads pool — 20 of the 306 SalesShift routes, and none of the 57 messaging routes. Deals, sequences, quotes, contracts, invoices, calendar, deliverability and webmail have no SDK method in any language; reach them over HTTP.

LanguageEntry pointMethodsStatus
Pythonvxsdk.Client(...).salesshift

Dicts and lists. Typed exceptions only (VxAuthError, VxValidationError, …).

23 sync · 23 asyncExercised live

Eight methods were called against a running control plane and all eight returned the documented shapes.

TypeScriptnew VxCloud(...).salesshift and .leads

The most thoroughly typed of the five — ~30 exported interfaces, overloads on searchLeads, exported caps, named lead errors.

22Read, not run

Read in full but not built or executed. getStats is the one call with no result interface (Record<string, unknown>).

Goc.SalesShift()

Typed structs for every request and response, plus MailableEmail(), NeedsReveal(), DisplayTotal() and Describe() helpers.

25Read, not run

Read in full but not compiled or executed. The routes behind it were exercised directly and through the Python SDK.

C++vxsdk::Client

Requests are typed (LeadFilters, LeadSearchRequest, LeadUpdate). Every method returns std::string — the raw JSON body.

21Not documented here

Lives in the SDK tree at sdk/cpp/ and has the same leads surface, but it is not part of this reference and has no response types or paging helper.

Javanew VxClient(...)

Requests use LeadQuery / LeadUpdate builders. Every call returns String — the raw JSON body.

26Not documented here

Lives at sdk/java/ as a single file with the same leads surface. Four static helpers exist so a caller can explain a failure without parsing the JSON.

All five implement one written contract, so "reveal" costs the same thing and a masked address looks the same everywhere. Two rules matter more than the rest: leads are not mailable until they are converted, and an unrevealed address is a mask, not an address — the Python and Go bindings refuse a masked address on the send path rather than let it reach a real domain.

Two things that are built but undemonstrated

Everything else named on this page was verified working against the live system. These two were not, and it would be dishonest to let a rollout plan assume otherwise.

OAuth mailbox connect has never had a real consent

The flow is fully built — PKCE, tokens in Vault, XOAUTH2, refresh — and a real send completes AUTH XOAUTH2 → 250 queued. But no Microsoft or Google mailbox has ever consented in this deployment, so the final SMTP hop to a real provider is unproven. Affects the webmail OAuth connect, reconnect and callback routes.

Call transcription and summary have never run on real data

No organization here has an AI provider key configured, which is the condition the transcription path checks. Every recording therefore ends at status="unavailable". The recording upload, finalize and intelligence routes are implemented; their AI output is undemonstrated.

The full route reference

SalesShift ships its own documentation app inside the SalesShift web app, served at /docs http://localhost:3020/docs when that app’s dev server is running. Go there for the per-route reference: request and response shapes, error cases, and which routes were called live versus read in source.

These VxCloud docs cover the parts of SalesShift you reach with platform tooling — the vxcli salesshift command group, the SDK methods, and the guides above.

Was this page helpful?