Find the IDs you need
Most mutations here take aspaceId, a modelId (project), an accountId, or a sandboxConfigId/sandboxIntegrationId. Start from viewer for spaces and projects, and from account for account-scoped sandbox resources:
sandboxConfigs and sandboxIntegrations are account-scoped, so this returns every config and credential the account has, not just the current space’s. See Using global node IDs for resolving a GID you already have (for example from a URL) with node.
List sandbox jobs and automations in a space
Once you have a space GID, list its recent sandbox jobs and configured automations in one call:automationId on a job is null for manual jobs and Setup Repo sessions, so filter on it to separate ad-hoc runs from automation-spawned ones. Reference: sandboxJobs and automations on Space.
Create a sandbox integration and attach it to a config
A sandbox integration stores the credential (for example a GitHub token) a sandbox injects as an environment variable. A sandbox config bundles a repo, a harness, and a set of integrations into a reusable preset:addIntegrationToSandboxConfig. Update or remove either resource later with updateSandboxIntegration, deleteSandboxIntegration, updateSandboxConfig, or deleteSandboxConfig. Reference: createSandboxIntegration, createSandboxConfig.
Launch a sandbox job and send it a follow-up message
Launch a job with a prompt, then steer it with a follow-up message while it’s running:createSandboxJob, sendSandboxMessage.
Snapshot a sandbox as a reusable template
A Setup Repo session (isSetupSession: true on createSandboxJob) clones and configures a repo once so future jobs can boot from the result instead of repeating setup:
templateId comes back as a string, but sandboxTemplateId on createSandboxConfig/updateSandboxConfig is an Int (the underlying DB id), so convert it before linking the template to a config:
createSandboxTemplate, updateSandboxConfig.
Create a cron or metric-triggered automation, then trigger it now
An automation spawns sandbox jobs from asandboxConfigId on a schedule, either a fixed cadence or a metric threshold crossing. Provide exactly one of cron or metric:
- Cron
- Metric
Mutation
Variables
triggerAutomationNow still runs the normal admission gates (cooloff window, capacity, Signal issue limit), so it can be a no-op for an automation already at its cap. Pause an automation with setAutomationEnabled (enabled: false), repoint it to a different repo with setAutomationRepo (empty string clears the override), change its schedule with updateAutomation, or remove it with deleteAutomation (soft-delete). Reference: createAutomation, triggerAutomationNow.
Enable Signal on one project, or many at once
Enabling Signal lazily provisions the built-in Signal automation for the project if one doesn’t exist yet:setSignalEnabledBulk, which processes each project independently and reports per-project outcomes:
llmIntegrationId on either mutation only applies when enabled is true; disabling a project ignores it. Reference: setSignalEnabled, setSignalEnabledBulk.
Tune Signal’s schedule and agent config
Change how often Signal runs and the extra context injected into its prompt:cadenceSeconds must be between 4 hours (14400) and 30 days (2592000). To run Signal from a custom sandbox config instead of the shared built-in default, attach one:
resetSignalAgentConfig (modelId only); it detaches the custom config without deleting it, so you can reattach it later. Reference: updateSignalConfig, setSignalAgentConfig.
List Signal issues for a project and resolve or fix one
List the open and ignored issues Signal has filed for a project:hasAttachedRepo is true, launch a fix PR for the issue, borrowing the repo and GitHub credential from the automation that filed it:
openSignalIssueGitHubIssue with the same id input; it returns the new issue’s issueUrl. When you’re done with Signal on a project entirely, deleteSignal removes its automation and is a no-op if none exists. Reference: setSignalIssueStatus, openSignalIssuePR.
Gotchas and behavior notes
createAutomation.promptTemplateis required even when unused: set it to an empty string whenagentTemplateKeyis set, and to a real Gotext/templatestring otherwise.createAutomationandupdateAutomationboth require exactly one ofcronormetric. Sending both, or neither, is rejected.- ID typing is inconsistent:
jobIdis aString!onCreateSandboxTemplateInputandSendSandboxMessageInput, but anID!onCreateSandboxJobPayload.createSandboxTemplatelikewise returnstemplateIdas aString!, whilesandboxTemplateIdon the config mutations is anInt. Convert between them when chaining calls. setSignalEnabledandsetSignalEnabledBulkonly applyllmIntegrationIdwhenenabled: true; disabling ignores it.UpdateSignalConfigInput.cadenceSecondsmust be between 14400 (4 hours) and 2592000 (30 days).setAutomationRepoand the per-automationrepooncreateAutomationoverride the boundsandboxConfig’s ownrepo.SignalStatus.hasAttachedRepoandSignalIssue.hasAttachedReporeflect this effective, resolved repo, so checkingagentConfig.repoalone can be wrong.setSignalIssueStatus,openSignalIssuePR, andopenSignalIssueGitHubIssueare gated by project-update access on the issue’s owning project, not just space membership.deleteAutomationanddeleteSignalare both idempotent: deleting one that’s already gone is a no-op rather than an error.- The config and integration CRUD inputs accept an optional
spaceIdpurely to authorize via space membership; the underlying rows are always account-scoped, not space-scoped.