About twill-cloud-coding-agent
twill-cloud-coding-agent is a skill for running Twill coding workflows through its public v1 API. It covers cloud-workspace tasks and schedules, including monitoring and lifecycle operations.
Key features
- 01Create and manage coding tasks
- 02List repositories, tasks, and jobs
- 03Send task messages and cancel runs
- 04Stream job logs
- 05Create and manage scheduled tasks
- 06Export Claude Code sessions
Use cases
- 01Start a coding task from a cloud workspace
- 02Check task results and job logs
- 03Schedule recurring coding work
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ twillai/ skills --skill twill-cloud-coding-agentAfter installing, type/twill-cloud-coding-agentin Claude Code to confirm it loaded.
Details
From the project READMETwill Cloud Coding Agent
Use this skill to run Twill workflows through the public v1 API.
Setup
Set API key and optional base URL:
export TWILL_API_KEY="your_api_key"
export TWILL_BASE_URL="${TWILL_BASE_URL:-https://twill.ai}"
All API calls use:
Authorization: Bearer $TWILL_API_KEY
Use this helper to reduce repetition:
api() {
curl -sS "$@" -H "Authorization: Bearer $TWILL_API_KEY" -H "Content-Type: application/json"
}
API keys belong to a cloud workspace and only reach its cloud tasks. Keys from a personal workspace are rejected, and local project chats (Twill Desktop) are not visible through the API: they return 404 or are omitted from lists.
Errors are JSON { "error": { "code", "message", "details"? } }. Rate limits are 100 requests/minute and 1,000/hour per key; a 429 includes Retry-After.
Endpoint Coverage (Public v1)
GET /api/v1/auth/meGET /api/v1/repositoriesPOST /api/v1/tasksGET /api/v1/tasksGET /api/v1/tasks/:taskIdOrSlugPOST /api/v1/tasks/:taskIdOrSlug/messagesGET /api/v1/tasks/:taskIdOrSlug/jobsPOST /api/v1/tasks/:taskIdOrSlug/cancelPOST /api/v1/tasks/:taskIdOrSlug/archiveGET /api/v1/tasks/:taskIdOrSlug/teleport/claudeGET /api/v1/jobs/:jobId/logs/streamPOST /api/v1/jobs/:jobId/cancelGET /api/v1/scheduled-tasksPOST /api/v1/scheduled-tasksGET /api/v1/scheduled-tasks/:scheduledTaskIdPATCH /api/v1/scheduled-tasks/:scheduledTaskIdDELETE /api/v1/scheduled-tasks/:scheduledTaskIdPOST /api/v1/scheduled-tasks/:scheduledTaskId/pausePOST /api/v1/scheduled-tasks/:scheduledTaskId/resume
There is no plan-approval endpoint. Plans and native permission questions are answered in the Twill task chat.
Auth and Discovery
Validate key and workspace context:
curl -sS "$TWILL_BASE_URL/api/v1/auth/me" -H "Authorization: Bearer $TWILL_API_KEY"
Returns workspaceId, userId, apiKeyId, workspaceName, workspaceSlug.
List available GitHub repositories for the workspace:
curl -sS "$TWILL_BASE_URL/api/v1/repositories" -H "Authorization: Bearer $TWILL_API_KEY"
Returns { repositories: [{ fullName, defaultBranch, description }] }.
Tasks
Create Task
api -X POST "$TWILL_BASE_URL/api/v1/tasks" -d '{"command":"Fix flaky tests in CI"}'
Repository and branch are not accepted in the request body. The agent picks from the workspace's connected repos at run time.
Required fields:
command
Optional fields:
agent: a completeprovider/modelid, for exampleclaude-code/sonnet,claude-code/opus,codex/gpt-5.5,open-code/openai/gpt-5.4. Provider-only values such ascodexare rejected. Omit it to use the workspace's routing defaults.userIntent(SWE,DEV_ENVIRONMENT,SCHEDULE): defaults toSWE. LegacyPLAN,ASKandGOALare still accepted but run asSWE.reasoningEffort(low,medium,high,xhigh,max,ultra)parentId(id of an existing task to spawn this one from)titlefiles(array of{ filename, mediaType, url }, whereurlmust be adata:URL such asdata:text/plain;base64,...; remotehttp(s):URLs are rejected)
To have the agent plan first, start command with /plan. The user reviews and approves the plan in the Twill task chat.
Response (201) is { task: { id, slug, title, url }, job: { id, status } }. Always report task.url back to the user.
List Tasks
curl -sS "$TWILL_BASE_URL/api/v1/tasks?limit=20&cursor=BASE64_CURSOR" -H "Authorization: Bearer $TWILL_API_KEY"
Supports cursor pagination via limit (default 20, max 100) and cursor. Response is { tasks, nextCursor }; each task includes id, slug, title, url, createdAt, latestJobStatus, and prs (array of { repoFullName, prNumber, prUrl, title, state }, where state is open, merged or closed).
Get Task Details
curl -sS "$TWILL_BASE_URL/api/v1/tasks/TASK_ID_OR_SLUG" -H "Authorization: Bearer $TWILL_API_KEY"
Returns task (id, slug, title, url, createdAt, updatedAt, prs) and latestJob (id, status, type, agentProvider, startedAt, completedAt, plan, planOutcome, finalAnswer), or latestJob: null.
Send Follow-Up Message
api -X POST "$TWILL_BASE_URL/api/v1/tasks/TASK_ID_OR_SLUG/messages" -d '{"message":"Please prioritize login flow first"}'
Sending a message cancels any in-flight job for the task and starts a fresh run with this message. The response is { job: { id, status } }.
Optional fields: userIntent, reasoningEffort, files (same rules as create), and agent. agent may change the model but not the harness: switching from claude-code/... to codex/... returns 400. Start a new task to use another harness.
List Task Jobs
curl -sS "$TWILL_BASE_URL/api/v1/tasks/TASK_ID_OR_SLUG/jobs?limit=30&cursor=BASE64_CURSOR" -H "Authorization: Bearer $TWILL_API_KEY"
Supports cursor pagination:
limitdefaults to30(max100)cursorfetches older pages- response is
{ jobs, nextCursor }; each job hasid,status,type,agentProvider,finalAnswer,plan,planOutcome,error,createdAt,completedAt
Cancel Task
api -X POST "$TWILL_BASE_URL/api/v1/tasks/TASK_ID_OR_SLUG/cancel" -d '{}'
Archive Task
api -X POST "$TWILL_BASE_URL/api/v1/tasks/TASK_ID_OR_SLUG/archive" -d '{}'
Export Claude Teleport Session
curl -sS "$TWILL_BASE_URL/api/v1/tasks/TASK_ID_OR_SLUG/teleport/claude" -H "Authorization: Bearer $TWILL_API_KEY" -o session.tar
Returns a tar of the task's Claude Code session JSONL files (headers X-Twill-Session-Id, X-Twill-Job-Id, X-Twill-File-Count). Only works for Claude Code tasks while the task sandbox is still alive; otherwise it returns 400, 404 or 409.
Jobs
Stream Job Logs (SSE)
curl -N "$TWILL_BASE_URL/api/v1/jobs/JOB_ID/logs/stream" -H "Authorization: Bearer $TWILL_API_KEY" -H "Accept: text/event-stream"
Each data: line is a JSON object with a type:
connected: first event.- Finished jobs:
trace_url(url,expiresAt), a short-lived signed URL to download the full trace, thenhistorical_completeandcomplete(status:completed,failedorcancelled). - Running jobs:
trace_chunks(signed chunk URLs) andtrace_recordsfor history, thenhistorical_complete, then live log and status events untilcomplete. error: the stream failed.
To get a job's result without parsing the trace, prefer finalAnswer from Get Task Details or List Task Jobs.
Cancel Job
api -X POST "$TWILL_BASE_URL/api/v1/jobs/JOB_ID/cancel" -d '{}'
Scheduled Tasks
Creating scheduled tasks requires a paid plan (Pro or Max); otherwise the API returns 403.
List and Create
curl -sS "$TWILL_BASE_URL/api/v1/scheduled-tasks" -H "Authorization: Bearer $TWILL_API_KEY"
api -X POST "$TWILL_BASE_URL/api/v1/scheduled-tasks" -d '{
"title":"Daily triage",
"message":"Review urgent issues and open tasks",
"cronExpression":"0 9 * * 1-5",
"timezone":"America/New_York",
"agentProviderId":"claude-code/sonnet"
}'
Required: title (max 200 chars), message, cronExpression.
Optional: timezone (IANA name, defaults to "UTC"), agentProviderId (complete provider/model override, e.g. claude-code/sonnet, codex/gpt-5.5). The server does not validate agentProviderId when saving, so an invalid id only fails when the schedule runs.
Repository and branch are not part of the scheduled-task payload. Each run picks repos at dispatch time, like one-shot tasks.
Response is { scheduledTask: { id, workspaceId, createdById, title, message, cronExpression, timezone, nextRunAt, lastRunAt, enabled, agentProviderId, createdAt, updatedAt } }.
Read, Update, Delete
curl -sS "$TWILL_BASE_URL/api/v1/scheduled-tasks/SCHEDULED_TASK_ID" -H "Authorization: Bearer $TWILL_API_KEY"
api -X PATCH "$TWILL_BASE_URL/api/v1/scheduled-tasks/SCHEDULED_TASK_ID" -d '{
"message":"Updated instructions",
"cronExpression":"0 10 * * 1-5",
"agentProviderId":"codex/gpt-5.5"
}'
curl -sS -X DELETE "$TWILL_BASE_URL/api/v1/scheduled-tasks/SCHEDULED_TASK_ID" -H "Authorization: Bearer $TWILL_API_KEY"
PATCH accepts any subset of title, message, cronExpression, timezone, agentProviderId (pass null to clear the override). DELETE returns { "success": true }.
Pause and Resume
api -X POST "$TWILL_BASE_URL/api/v1/scheduled-tasks/SCHEDULED_TASK_ID/pause" -d '{}'
api -X POST "$TWILL_BASE_URL/api/v1/scheduled-tasks/SCHEDULED_TASK_ID/resume" -d '{}'
Behavior
- Use
userIntentSWE(default),DEV_ENVIRONMENTorSCHEDULE. For planning, prefix the command with/planinstead of sendingPLAN. - Do not send
repository/branchon tasks orrepositoryUrl/baseBranchon scheduled tasks. Twill picks repos and branches at run time from workspace context. - Always pass
agent/agentProviderIdas a completeprovider/modelid. - Inline attachments as
data:URLs. - Create the task, report
task.url, and only poll or stream logs when requested. - Plan approvals and permission questions happen in the Twill task chat. A follow-up message does not answer them.
- Ask for
TWILL_API_KEYif missing. - Do not print API keys or other secrets.