Overview
The Drafts API allows you to save, manage, and queue prompts for task attempts. Useful for preparing follow-up instructions or retry strategies before execution. Base URL:http://localhost:8887/api/task-attempts/:id/drafts
Save Draft
Save a draft prompt for a task attempt.POST /api/task-attempts/:id/drafts
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
content | string | ✅ | Draft prompt content |
type | enum | ✅ | Draft type: follow_up, retry, initial |
metadata | object | ⚠️ | Additional metadata |
curl -X POST http://localhost:8887/api/task-attempts/attempt_xyz789/drafts \
-H "Content-Type: application/json" \
-d '{
"content": "Add unit tests for the authentication functions",
"type": "follow_up",
"metadata": {
"priority": "high",
"category": "testing"
}
}'
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/drafts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
content: 'Add unit tests for the authentication functions',
type: 'follow_up',
metadata: {
priority: 'high',
category: 'testing'
}
})
});
const data = await response.json();
import requests
response = requests.post(
'http://localhost:8887/api/task-attempts/attempt_xyz789/drafts',
json={
'content': 'Add unit tests for the authentication functions',
'type': 'follow_up',
'metadata': {
'priority': 'high',
'category': 'testing'
}
}
)
data = response.json()
{
"success": true,
"data": {
"id": "draft_abc123",
"taskAttemptId": "attempt_xyz789",
"content": "Add unit tests for the authentication functions",
"type": "follow_up",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z",
"metadata": {
"priority": "high",
"category": "testing"
}
}
}
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "Missing required field: content"
}
}
Get Draft
Retrieve a saved draft.GET /api/task-attempts/:attemptId/drafts/:draftId
curl http://localhost:8887/api/task-attempts/attempt_xyz789/drafts/draft_abc123
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/drafts/draft_abc123');
const data = await response.json();
import requests
response = requests.get('http://localhost:8887/api/task-attempts/attempt_xyz789/drafts/draft_abc123')
data = response.json()
{
"success": true,
"data": {
"id": "draft_abc123",
"taskAttemptId": "attempt_xyz789",
"content": "Add unit tests for the authentication functions",
"type": "follow_up",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
}
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Draft not found"
}
}
Delete Draft
Delete a saved draft.DELETE /api/task-attempts/:attemptId/drafts/:draftId
curl -X DELETE http://localhost:8887/api/task-attempts/attempt_xyz789/drafts/draft_abc123
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/drafts/draft_abc123', {
method: 'DELETE'
});
const data = await response.json();
import requests
response = requests.delete('http://localhost:8887/api/task-attempts/attempt_xyz789/drafts/draft_abc123')
data = response.json()
{
"success": true,
"data": {
"deleted": true,
"draftId": "draft_abc123"
}
}
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Draft not found"
}
}
Save Follow-Up Draft
Save a draft for follow-up instructions to a running task.POST /api/task-attempts/:id/follow-up-draft
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
prompt | string | - | Follow-up instruction |
autoSend | boolean | false | Automatically send when ready |
sendAfter | string | null | Schedule send time |
curl -X POST http://localhost:8887/api/task-attempts/attempt_xyz789/follow-up-draft \
-H "Content-Type: application/json" \
-d '{
"prompt": "Also add integration tests for the login flow",
"autoSend": false,
"sendAfter": "2024-01-15T11:00:00Z"
}'
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/follow-up-draft', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'Also add integration tests for the login flow',
autoSend: false,
sendAfter: '2024-01-15T11:00:00Z'
})
});
const data = await response.json();
import requests
response = requests.post(
'http://localhost:8887/api/task-attempts/attempt_xyz789/follow-up-draft',
json={
'prompt': 'Also add integration tests for the login flow',
'autoSend': False,
'sendAfter': '2024-01-15T11:00:00Z'
}
)
data = response.json()
{
"success": true,
"data": {
"id": "draft_followup_abc123",
"taskAttemptId": "attempt_xyz789",
"prompt": "Also add integration tests for the login flow",
"autoSend": false,
"sendAfter": "2024-01-15T11:00:00Z",
"status": "scheduled",
"createdAt": "2024-01-15T10:30:00Z"
}
}
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "Missing required field: prompt"
}
}
Save Retry Follow-Up Draft
Save a draft for retry attempts with modified prompts.POST /api/task-attempts/:id/retry-follow-up-draft
curl -X POST http://localhost:8887/api/task-attempts/attempt_xyz789/retry-follow-up-draft \
-H "Content-Type: application/json" \
-d '{
"originalPrompt": "Implement authentication",
"retryPrompt": "Implement authentication using JWT with refresh tokens",
"retryReason": "Initial attempt didn'\''t include refresh token logic"
}'
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/retry-follow-up-draft', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
originalPrompt: 'Implement authentication',
retryPrompt: 'Implement authentication using JWT with refresh tokens',
retryReason: 'Initial attempt didn\'t include refresh token logic'
})
});
const data = await response.json();
import requests
response = requests.post(
'http://localhost:8887/api/task-attempts/attempt_xyz789/retry-follow-up-draft',
json={
'originalPrompt': 'Implement authentication',
'retryPrompt': 'Implement authentication using JWT with refresh tokens',
'retryReason': 'Initial attempt didn\'t include refresh token logic'
}
)
data = response.json()
{
"success": true,
"data": {
"id": "draft_retry_abc123",
"taskAttemptId": "attempt_xyz789",
"originalPrompt": "Implement authentication",
"retryPrompt": "Implement authentication using JWT with refresh tokens",
"retryReason": "Initial attempt didn't include refresh token logic",
"createdAt": "2024-01-15T10:35:00Z"
}
}
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "Missing required field: retryPrompt"
}
}
Delete Retry Follow-Up Draft
Delete a retry follow-up draft.DELETE /api/task-attempts/:id/retry-follow-up-draft/:draftId
curl -X DELETE http://localhost:8887/api/task-attempts/attempt_xyz789/retry-follow-up-draft/draft_retry_abc123
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/retry-follow-up-draft/draft_retry_abc123', {
method: 'DELETE'
});
const data = await response.json();
import requests
response = requests.delete('http://localhost:8887/api/task-attempts/attempt_xyz789/retry-follow-up-draft/draft_retry_abc123')
data = response.json()
{
"success": true,
"data": {
"deleted": true,
"draftId": "draft_retry_abc123"
}
}
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Draft not found"
}
}
Set Follow-Up Queue
Set a queue of follow-up prompts to be executed in sequence.POST /api/task-attempts/:id/follow-up-queue
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
queue | array | - | Ordered list of follow-up prompts |
queue[].prompt | string | - | Follow-up instruction |
queue[].order | integer | - | Execution order |
autoExecute | boolean | false | Auto-execute queue |
curl -X POST http://localhost:8887/api/task-attempts/attempt_xyz789/follow-up-queue \
-H "Content-Type: application/json" \
-d '{
"queue": [
{
"prompt": "Add input validation",
"order": 1
},
{
"prompt": "Add error handling",
"order": 2
},
{
"prompt": "Add unit tests",
"order": 3
}
],
"autoExecute": false
}'
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/follow-up-queue', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
queue: [
{ prompt: 'Add input validation', order: 1 },
{ prompt: 'Add error handling', order: 2 },
{ prompt: 'Add unit tests', order: 3 }
],
autoExecute: false
})
});
const data = await response.json();
import requests
response = requests.post(
'http://localhost:8887/api/task-attempts/attempt_xyz789/follow-up-queue',
json={
'queue': [
{'prompt': 'Add input validation', 'order': 1},
{'prompt': 'Add error handling', 'order': 2},
{'prompt': 'Add unit tests', 'order': 3}
],
'autoExecute': False
}
)
data = response.json()
{
"success": true,
"data": {
"taskAttemptId": "attempt_xyz789",
"queue": [
{
"id": "queue_item_1",
"prompt": "Add input validation",
"order": 1,
"status": "pending"
},
{
"id": "queue_item_2",
"prompt": "Add error handling",
"order": 2,
"status": "pending"
},
{
"id": "queue_item_3",
"prompt": "Add unit tests",
"order": 3,
"status": "pending"
}
],
"autoExecute": false,
"createdAt": "2024-01-15T10:30:00Z"
}
}
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "Queue must be an array with at least one item"
}
}
Set Draft Queue
Set a queue of draft prompts for task creation.POST /api/task-attempts/:id/draft-queue
curl -X POST http://localhost:8887/api/task-attempts/attempt_xyz789/draft-queue \
-H "Content-Type: application/json" \
-d '{
"queue": [
{
"title": "Implement user registration",
"description": "Create registration endpoint with email validation",
"order": 1
},
{
"title": "Implement user login",
"description": "Create login endpoint with JWT generation",
"order": 2
}
]
}'
const response = await fetch('http://localhost:8887/api/task-attempts/attempt_xyz789/draft-queue', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
queue: [
{
title: 'Implement user registration',
description: 'Create registration endpoint with email validation',
order: 1
},
{
title: 'Implement user login',
description: 'Create login endpoint with JWT generation',
order: 2
}
]
})
});
const data = await response.json();
import requests
response = requests.post(
'http://localhost:8887/api/task-attempts/attempt_xyz789/draft-queue',
json={
'queue': [
{
'title': 'Implement user registration',
'description': 'Create registration endpoint with email validation',
'order': 1
},
{
'title': 'Implement user login',
'description': 'Create login endpoint with JWT generation',
'order': 2
}
]
}
)
data = response.json()
{
"success": true,
"data": {
"projectId": "proj_abc123",
"queue": [
{
"id": "queue_draft_1",
"title": "Implement user registration",
"description": "Create registration endpoint with email validation",
"order": 1,
"status": "queued"
},
{
"id": "queue_draft_2",
"title": "Implement user login",
"description": "Create login endpoint with JWT generation",
"order": 2,
"status": "queued"
}
]
}
}
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "Queue must be an array with at least one item"
}
}
Stream Project Drafts
Stream real-time updates of project drafts via WebSocket.ws://localhost:8887/ws/projects/:projectId/drafts
const projectId = 'proj_abc123';
const ws = new WebSocket(`ws://localhost:8887/ws/projects/${projectId}/drafts`);
ws.onmessage = (event) => {
const update = JSON.parse(event.data);
switch (update.type) {
case 'draft_created':
console.log('New draft:', update.draft);
break;
case 'draft_updated':
console.log('Draft updated:', update.draft);
break;
case 'draft_deleted':
console.log('Draft deleted:', update.draftId);
break;
}
};
Use Cases
Batch Follow-Ups
Queue multiple follow-up instructions for sequential execution:// Set up a series of refinements
await forge.attempts.setFollowUpQueue('attempt_123', {
queue: [
{ prompt: 'Add TypeScript types', order: 1 },
{ prompt: 'Add JSDoc comments', order: 2 },
{ prompt: 'Add unit tests', order: 3 },
{ prompt: 'Add integration tests', order: 4 }
],
autoExecute: true
});
Scheduled Follow-Ups
Schedule follow-up instructions for later:// Schedule a follow-up for after code review
await forge.attempts.saveFollowUpDraft('attempt_123', {
prompt: 'Address code review comments',
autoSend: true,
sendAfter: new Date(Date.now() + 2 * 60 * 60 * 1000) // 2 hours from now
});
Retry Strategy
Save retry prompts with improved instructions:// If first attempt fails, retry with more specific instructions
await forge.attempts.saveRetryFollowUpDraft('attempt_123', {
originalPrompt: 'Add authentication',
retryPrompt: 'Add authentication using Passport.js with JWT strategy and refresh tokens',
retryReason: 'Need more specific implementation approach'
});
SDK Examples
JavaScript/TypeScript
import { ForgeClient } from '@automagik/forge-sdk';
const forge = new ForgeClient();
// Save a draft
const draft = await forge.attempts.saveDraft('attempt_123', {
content: 'Add error handling',
type: 'follow_up',
metadata: { priority: 'high' }
});
// Get draft
const savedDraft = await forge.attempts.getDraft('attempt_123', 'draft_abc');
// Delete draft
await forge.attempts.deleteDraft('attempt_123', 'draft_abc');
// Save follow-up draft with auto-send
await forge.attempts.saveFollowUpDraft('attempt_123', {
prompt: 'Add unit tests',
autoSend: true,
sendAfter: new Date('2024-01-15T11:00:00Z')
});
// Set follow-up queue
await forge.attempts.setFollowUpQueue('attempt_123', {
queue: [
{ prompt: 'Add validation', order: 1 },
{ prompt: 'Add tests', order: 2 }
],
autoExecute: false
});
// Stream drafts
const draftStream = forge.projects.streamDrafts('proj_123');
draftStream.on('draft_created', (draft) => {
console.log('New draft:', draft);
});
Python
from automagik_forge import ForgeClient
forge = ForgeClient()
# Save draft
draft = forge.attempts.save_draft(
'attempt_123',
content='Add error handling',
type='follow_up'
)
# Set follow-up queue
forge.attempts.set_follow_up_queue(
'attempt_123',
queue=[
{'prompt': 'Add validation', 'order': 1},
{'prompt': 'Add tests', 'order': 2}
],
auto_execute=False
)
Best Practices
Order Follow-Ups Logically
// Good ✅
queue: [
{ prompt: 'Add feature', order: 1 },
{ prompt: 'Add tests', order: 2 },
{ prompt: 'Add docs', order: 3 }
]
// Avoid ❌
queue: [
{ prompt: 'Add docs', order: 1 },
{ prompt: 'Add feature', order: 2 },
{ prompt: 'Add tests', order: 3 }
]
Use Auto-Execute Carefully
Only auto-execute follow-ups when you’re confident they won’t require review:
// Safe for auto-execute ✅
{ prompt: 'Format code', autoExecute: true }
// Review first ❌
{ prompt: 'Refactor architecture', autoExecute: true }
Include Context in Retries
// Good ✅
{
retryPrompt: 'Use bcrypt for password hashing with salt rounds of 12',
retryReason: 'Initial attempt used plain text storage'
}
// Unclear ❌
{
retryPrompt: 'Fix it',
retryReason: 'Didn't work'
}
Clean Up Old Drafts
// Delete obsolete drafts
const drafts = await forge.attempts.listDrafts('attempt_123');
for (const draft of drafts) {
if (draft.createdAt < oneWeekAgo) {
await forge.attempts.deleteDraft('attempt_123', draft.id);
}
}
Next Steps
Attempts API
Task attempt execution
WebSockets
Real-time draft updates
Tasks API
Create tasks from drafts
Workflows
Draft-based workflows

