Skip to content
SSalesShiftDocs
API reference

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).

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

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
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

Top-level keys
{
  "dkim_valid": "…",
  "dmarc_valid": "…",
  "domain": "…",
  "guidance": "…",
  "spf_valid": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Valid domain required
#post-api-v1-salesshift-settings-dns-checksettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:530Implemented 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/settings/integrationsCalled liveThe organization's configured integrations (email, AI, payment providers).
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

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

Response · 200

Observed shape
{
  "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"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-settings-integrationssettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:89Called 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/settings/integrationsNot exercised hereStore credentials in Vault and upsert the metadata row.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+data

Request body (required) — IntegrationConfigIn

FieldTypeRequiredNotes
integration_typestringrequired
providerstringrequired
credentialsobjectoptional
metadataobjectoptional
is_defaultbooleanoptionalDefault true.
instance_keystring?optional

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

Request

curl
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

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

Errors

Statusdetail
400Unsupported provider: {...}/{...}
400Missing 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.
400instance_key must be a lowercase slug matching ^[a-z0-9-]{2,40}$
502Failed to store credentials in Vault{...}
#post-api-v1-salesshift-settings-integrationssettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:105Implemented 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/settings/integrations/{integration_id}Not exercised hereDelete one integration.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
integration_idstring(uuid)required

Request

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

Response · 200

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

Errors

Statusdetail
404Integration not found
#delete-api-v1-salesshift-settings-integrations-integration-idsettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:255Implemented 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/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.

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

Path parameters

NameTypeRequiredNotes
integration_idstring(uuid)required

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/settings/integrations/{integration_id}/test' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

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

Errors

Statusdetail
404Integration not found
#post-api-v1-salesshift-settings-integrations-integration-id-testsettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_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/settings/mailboxesCalled liveThe organization's configured sending mailboxes.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

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

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    "<empty list>"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-settings-mailboxessettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:577Called 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/settings/mailboxesNot exercised hereRegister a sending mailbox for the organization.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+custom

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
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

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

Errors

Statusdetail
400Valid from_email required
409Mailbox already exists
#post-api-v1-salesshift-settings-mailboxessettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:597Implemented 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/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).

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/settings/poll-replies-now' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "success": "…",
  "summary": "…"
}
Top-level keys read from the handler's return statements.
#post-api-v1-salesshift-settings-poll-replies-nowsettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:628Implemented 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/settings/suppressionsCalled liveUp to 500 suppressed addresses for the organization.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

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

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    "<empty list>"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-settings-suppressionssettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:452Called 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/settings/suppressionsNot exercised hereAdd an address to the organization's suppression list.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+custom

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
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

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

Errors

Statusdetail
400Valid email required
#post-api-v1-salesshift-settings-suppressionssettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:476Implemented 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/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).

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

Path parameters

NameTypeRequiredNotes
suppression_idstring(uuid)required

Request

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

Response · 200

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

Errors

Statusdetail
404Suppression not found
#delete-api-v1-salesshift-settings-suppressions-suppression-idsettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:505Implemented 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/settings/teamCalled liveEvery user of the current organization (active and deactivated).
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Request

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

Response · 200

Observed shape
{
  "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"
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-settings-teamteam_router · vxcloud_fastapiclient/app/services/salesshift/team_router.py:123Called 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/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.

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

Path parameters

NameTypeRequiredNotes
user_idintegerrequired

Request body (required) — MemberPatchIn

FieldTypeRequiredNotes
rolestring?optional
is_activeboolean?optional

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

Request

curl
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

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

Errors

Statusdetail
400Role must be one of: {...}
400You cannot remove your own admin role — ask another admin
400You cannot deactivate yourself
#patch-api-v1-salesshift-settings-team-user-idteam_router · vxcloud_fastapiclient/app/services/salesshift/team_router.py:297Implemented 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/settings/team/{user_id}Not exercised hereDeactivate a teammate; admin only, and the caller cannot deactivate themselves.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
user_idintegerrequired

Request

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

Response · 200

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

Errors

Statusdetail
400You cannot deactivate yourself
#delete-api-v1-salesshift-settings-team-user-idteam_router · vxcloud_fastapiclient/app/services/salesshift/team_router.py:345Implemented 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/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.

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

Request body (required) — InviteIn

FieldTypeRequiredNotes
emailstringrequired
usernamestringrequired
first_namestringoptionalDefault "".
last_namestringoptionalDefault "".
rolestringoptionalDefault "member".

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

Request

curl
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

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

Errors

Statusdetail
400Role must be one of: {...}
400computed at runtime: str(first.get('msg') or exc)
400computed at runtime: str(exc)
500Failed to create teammate: {...}
402computed 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." )
#post-api-v1-salesshift-settings-team-inviteteam_router · vxcloud_fastapiclient/app/services/salesshift/team_router.py:206Implemented 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/statsCalled liveDashboard counters: contacts, companies, open deals, active sequences and the email funnel.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
bare-model

Request

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

Response · 200

Observed shape
{
  "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"
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-statssettings_router · vxcloud_fastapiclient/app/services/salesshift/settings_router.py:645Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.