Settings and team
Org integrations, suppressions, sending mailboxes, DNS checks, dashboard counters and teammate management.
16 endpoints· 5 called live· 11 not exercised here· verified against http://127.0.0.1:8741
16 endpoints
POST/api/v1/salesshift/settings/dns-checkNot exercised hereCheck SPF / DMARC TXT records for a sending domain (DKIM needs the selector, so it reports 'unknown' unless one is provided).
Check SPF / DMARC TXT records for a sending domain (DKIM needs the selector, so it reports 'unknown' unless one is provided).
Request body (required)
Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.
dkim_selectordomain
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/dns-check' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "dkim_selector": "<value>", "domain": "<value>" }'Response · 200
{
"dkim_valid": "…",
"dmarc_valid": "…",
"domain": "…",
"guidance": "…",
"spf_valid": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Valid domain required |
GET/api/v1/salesshift/settings/integrationsCalled liveThe organization's configured integrations (email, AI, payment providers).
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/settings/integrations' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"data": [
{
"id": "str",
"organization_id": "str",
"integration_type": "str",
"provider": "str",
"metadata_json": {
"note": "..."
},
"is_active": "bool",
"is_default": "bool",
"spf_valid": "bool",
"dkim_valid": "bool",
"dmarc_valid": "bool",
"last_tested_at": "str",
"last_test_status": "str",
"last_test_error": "null",
"created_at": "str"
},
"...x3"
]
}POST/api/v1/salesshift/settings/integrationsNot exercised hereStore credentials in Vault and upsert the metadata row.
Request body (required) — IntegrationConfigIn
| Field | Type | Required | Notes |
|---|---|---|---|
| integration_type | string | required | |
| provider | string | required | |
| credentials | object | optional | |
| metadata | object | optional | |
| is_default | boolean | optional | Default true. |
| instance_key | string? | optional |
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/integrations' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "integration_type": "<string>", "provider": "<string>", "credentials": {}, "metadata": {}, "is_default": true, "instance_key": "<string>" }'Response · 201
{
"data": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Unsupported provider: {...}/{...} |
| 400 | Missing credential fields: {...} |
| 400 | '{...}' cannot be the default {...} provider — no part of SalesShift uses it yet, and making it the default would disable the one that works. Save it with is_default: false. |
| 400 | instance_key must be a lowercase slug matching ^[a-z0-9-]{2,40}$ |
| 502 | Failed to store credentials in Vault{...} |
DELETE/api/v1/salesshift/settings/integrations/{integration_id}Not exercised hereDelete one integration.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| integration_id | string(uuid) | required |
Request
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/settings/integrations/{integration_id}' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "…"
}Errors
| Status | detail |
|---|---|
| 404 | Integration not found |
POST/api/v1/salesshift/settings/integrations/{integration_id}/testNot exercised hereRead the credentials back out of Vault and use them against the provider for real — a Vault round-trip alone proves nothing about whether the key, host, port or password still work.
Read the credentials back out of Vault and use them against the provider for real — a Vault round-trip alone proves nothing about whether the key, host, port or password still work.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| integration_id | string(uuid) | required |
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/integrations/{integration_id}/test' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"error": "…",
"status": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 404 | Integration not found |
GET/api/v1/salesshift/settings/mailboxesCalled liveThe organization's configured sending mailboxes.
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/settings/mailboxes' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"data": [
"<empty list>"
]
}POST/api/v1/salesshift/settings/mailboxesNot exercised hereRegister a sending mailbox for the organization.
Request body (required)
Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.
daily_capfrom_emailfrom_namewarmup_enabled
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/mailboxes' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "daily_cap": "<value>", "from_email": "<value>", "from_name": "<value>", "warmup_enabled": "<value>" }'Response · 201
{
"id": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Valid from_email required |
| 409 | Mailbox already exists |
POST/api/v1/salesshift/settings/poll-replies-nowNot exercised hereManually run one IMAP reply-detection pass (the background loop also runs this every ~5 minutes).
Manually run one IMAP reply-detection pass (the background loop also runs this every ~5 minutes).
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/poll-replies-now' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "…",
"summary": "…"
}GET/api/v1/salesshift/settings/suppressionsCalled liveUp to 500 suppressed addresses for the organization.
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/settings/suppressions' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"data": [
"<empty list>"
]
}POST/api/v1/salesshift/settings/suppressionsNot exercised hereAdd an address to the organization's suppression list.
Request body (required)
Untyped Dict[str, Any] body — there is no Pydantic model, so these are the field names the handler actually reads.
emailreason
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/suppressions' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "email": "<value>", "reason": "<value>" }'Response · 201
{
"already_present": "…",
"id": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Valid email required |
DELETE/api/v1/salesshift/settings/suppressions/{suppression_id}Not exercised hereRelease an address.
Release an address. Suppression is a hard gate on every send, so a typo or a one-off soft bounce has to be reversible — the caller is expected to confirm first (the UI warns on complaint/hard-bounce rows).
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| suppression_id | string(uuid) | required |
Request
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/settings/suppressions/{suppression_id}' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "…"
}Errors
| Status | detail |
|---|---|
| 404 | Suppression not found |
GET/api/v1/salesshift/settings/teamCalled liveEvery user of the current organization (active and deactivated).
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/settings/team' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"success": "bool",
"data": [
{
"id": "int",
"username": "str",
"email": "str",
"first_name": "str",
"last_name": "str",
"role": "str",
"is_active": "bool",
"date_joined": "str",
"last_login": "str",
"is_you": "bool"
},
"...x5"
],
"your_role": "str"
}PATCH/api/v1/salesshift/settings/team/{user_id}Not exercised hereChange a teammate's role, or bring a deactivated one back.
Change a teammate's role, or bring a deactivated one back. Reactivation matters: deactivation used to be a one-way door — the roster kept rendering the row, but nothing anywhere could flip is_active back on.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| user_id | integer | required |
Request body (required) — MemberPatchIn
| Field | Type | Required | Notes |
|---|---|---|---|
| role | string? | optional | |
| is_active | boolean? | optional |
Values in the request below are typed placeholders, not sample data.
Request
curl -X PATCH 'https://api.vxcloud.io/api/v1/salesshift/settings/team/{user_id}' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "role": "<string>", "is_active": false }'Response · 200
{
"id": "…",
"is_active": "…",
"role": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Role must be one of: {...} |
| 400 | You cannot remove your own admin role — ask another admin |
| 400 | You cannot deactivate yourself |
DELETE/api/v1/salesshift/settings/team/{user_id}Not exercised hereDeactivate a teammate; admin only, and the caller cannot deactivate themselves.
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
| user_id | integer | required |
Request
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/settings/team/{user_id}' \
-H "Authorization: Bearer $SS_TOKEN"Response · 200
{
"id": "…",
"is_active": "…",
"success": "…"
}Errors
| Status | detail |
|---|---|
| 400 | You cannot deactivate yourself |
POST/api/v1/salesshift/settings/team/inviteNot exercised hereCreate a teammate account in THIS org via the shared tenant-user creator, then email them their credentials.
Create a teammate account in THIS org via the shared tenant-user creator, then email them their credentials.
Request body (required) — InviteIn
| Field | Type | Required | Notes |
|---|---|---|---|
| string | required | ||
| username | string | required | |
| first_name | string | optional | Default "". |
| last_name | string | optional | Default "". |
| role | string | optional | Default "member". |
Values in the request below are typed placeholders, not sample data.
Request
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/team/invite' \
-H "Authorization: Bearer $SS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "email": "<string>", "username": "<string>", "first_name": "", "last_name": "", "role": "member" }'Response · 201
{
"email_sent": "…",
"success": "…",
"user": "…"
}Errors
| Status | detail |
|---|---|
| 400 | Role must be one of: {...} |
| 400 | computed at runtime: str(first.get('msg') or exc) |
| 400 | computed at runtime: str(exc) |
| 500 | Failed to create teammate: {...} |
| 402 | computed at runtime: # entitlements.assert_seat_headroom
detail = (
f"{ent.plan_name} includes {ent.users} users and this workspace has "
f"{current}. Upgrade to invite more."
) |
GET/api/v1/salesshift/statsCalled liveDashboard counters: contacts, companies, open deals, active sequences and the email funnel.
Request
curl 'https://api.vxcloud.io/api/v1/salesshift/stats' \
-H "Authorization: Bearer $SS_TOKEN"import vxsdk
client = vxsdk.Client(access_token="$SS_TOKEN", vxcloud_url="https://api.vxcloud.io")
ss = client.salesshift
ss.get_stats()import { VxCloud } from '@vxcloud/sdk';
const vx = new VxCloud({
accessToken: process.env.SS_TOKEN!,
vxcloudURL: 'https://api.vxcloud.io',
});
await vx.salesshift.getStats();import vxsdk "github.com/prodxcloud/vxcloud"
c, err := vxsdk.New(ctx,
vxsdk.WithJWT(os.Getenv("SS_TOKEN"), ""),
vxsdk.WithVxCloudURL("https://api.vxcloud.io"),
)
ss := c.SalesShift()
stats, err := ss.GetStats(ctx)Response · 200
{
"contacts": "int",
"companies": "int",
"open_deals": "int",
"open_pipeline_value": "float",
"active_sequences": "int",
"open_tasks": "int",
"email_stats": {
"sent": "int",
"delivered": "int",
"opened": "int",
"replied": "int",
"bounced": "int"
},
"reply_categories": {
"follow_up_question": "int",
"willing_to_meet": "int"
}
}