We need all Cursor Cloud Agent workloads for our team to run only on our self-hosted worker (machines in our account that connect outbound to Cursor). We must not use Cursor’s hosted cloud agent VMs for these runs.
Programmatic launches via POST /v0/agents (or any supported server-to-server API)
What we’re seeing
When we trigger agents through the API (POST to the agents endpoint with our API key), runs appear to be Cursor-hosted cloud agents, not our self-hosted worker.
We have not found a clear setting in the dashboard that says “Automations: self-hosted only” or “API: route to worker pool X”.
We need official guidance on whether self-hosted-only execution is supported for both Automations and API, and exactly how to configure it.
Questions
Is it possible to restrict a team or workspace so that Automations run exclusively on self-hosted workers? If yes, where is that configured (dashboard path, org/team setting, worker labels, feature flag)?
Same question for the Agents API: Can POST /v0/agents (or the current supported equivalent) be constrained to only dispatch work to our self-hosted pool? If yes, what request fields, headers, or account settings are required?
If API launches cannot target self-hosted workers today, is that by design? What is the recommended supported path to start self-hosted runs from automation outside Slack (e.g. webhook Automation only, CI, other)?
How can we verify in the UI or in run metadata that a given execution used self-hosted vs Cursor-hosted (so we can audit compliance)?
Are there Enterprise / Private Cloud Agents options that are required for “self-hosted only” enforcement, or should this work on standard team self-hosted worker setup?
Context (brief)
We operate a self-hosted worker per Cursor’s documentation (outbound HTTPS, worker registered to our team).
Compliance / data residency: we need execution on our infrastructure, not shared Cursor VMs.
We’re happy to share non-sensitive screenshots of our Cloud Agents / Automations settings if that helps, but we need a definitive answer on routing and any gaps between Automations, API, and self-hosted workers.
The key setting you need is “Require Self-hosted Agents for All Cloud Agents.” It’s in your team dashboard at cursor.com/dashboard under the Cloud Agents tab, inside the Self-hosted Agents section. When enabled, all cloud agent runs for your team are forced to your self-hosted workers, regardless of whether they come from the UI, Slack, or the API.
To answer your specific questions:
1-3. Automations + API enforcement: The “Require” toggle covers both. Once enabled, Slack Automations and API runs (POST /v0/agents) will all route to your self-hosted workers automatically. No per-request configuration needed.
If you want more granular control (before enabling the team-wide requirement), individual API requests can opt in by passing "usePrivateWorker": true in the POST body, and Slack commands support a private_worker option.
4. Verifying self-hosted vs Cursor-hosted: The Self-hosted Agents section of your dashboard shows all connected workers with Active/Idle status. Active workers link to the conversation they’re running. You can also query GET /v0/private-workers programmatically for audit purposes.
5. Plan requirement: Self-hosted agents are a team feature. You should have access on your current plan.
If you don’t see the “Require Self-hosted Agents” toggle in your dashboard, make sure “Allow Self-hosted Agents” is enabled first (same section), and that you’re logged in as a team admin.
This is a known bug on our side – the “Require Self-Hosted Pool for All Cloud Agents” toggle is failing to save for some teams. Our team is actively working on a fix.
In the meantime, you can still route individual runs to your self-hosted workers:
API (POST /v0/agents): Pass "usePrivateWorker": true in the request body
Slack Automations: Add private_worker as an option in the command
The “Allow Self-hosted Agents” toggle should work fine. Only the “Require” enforcement toggle is affected by this bug.
The fix is still in progress on our end. I understand this has been a long wait.
In the meantime, the per-request workarounds I mentioned earlier should still work.