Skip to content

Tasks API

Reference for creating and managing automation tasks.

Overview

Tasks are individual automation jobs executed by Browserman. Each task represents a single operation like posting a tweet, liking content, or any platform-specific action.

Task States

Tasks progress through several states:

  • pending - Task is queued, waiting to start
  • processing - Task is currently executing
  • completed - Task finished successfully
  • failed - Task encountered an error
  • timeout - Task exceeded time limit
  • cancelled - Task was cancelled by user

Create Task

Execute a platform-specific tool.

Endpoint:

POST /api/tasks

Headers:

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request Body:

json
{
  "platform": "twitter",
  "tool": "createTweet",
  "accountName": "my-account",
  "parameters": {
    "text": "Hello World!",
    "preferredEngine": "lite"
  }
}

Example:

bash
curl -X POST https://api.browserman.run/api/tasks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "twitter",
    "tool": "createTweet",
    "accountName": "my-twitter",
    "parameters": {
      "text": "Testing Browserman API! 🚀"
    }
  }'

Success Response:

json
{
  "success": true,
  "data": {
    "taskId": "task_abc123def456",
    "state": "pending",
    "platform": "twitter",
    "tool": "createTweet",
    "accountName": "my-twitter",
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

Error Response:

json
{
  "success": false,
  "error": {
    "code": "ACCOUNT_NOT_FOUND",
    "message": "Account 'my-twitter' not found for platform 'twitter'",
    "details": {
      "platform": "twitter",
      "accountName": "my-twitter"
    }
  }
}

Get Task Status

Retrieve the current status and result of a task.

Endpoint:

GET /api/tasks/:taskId

Example:

bash
curl https://api.browserman.run/api/tasks/task_abc123def456 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (Pending):

json
{
  "success": true,
  "data": {
    "taskId": "task_abc123def456",
    "state": "pending",
    "platform": "twitter",
    "tool": "createTweet",
    "accountName": "my-twitter",
    "createdAt": "2024-01-15T10:30:00Z",
    "queuePosition": 3
  }
}

Response (Processing):

json
{
  "success": true,
  "data": {
    "taskId": "task_abc123def456",
    "state": "processing",
    "platform": "twitter",
    "tool": "createTweet",
    "accountName": "my-twitter",
    "createdAt": "2024-01-15T10:30:00Z",
    "startedAt": "2024-01-15T10:30:05Z",
    "progress": {
      "step": "authenticating",
      "percentage": 30
    }
  }
}

Response (Completed):

json
{
  "success": true,
  "data": {
    "taskId": "task_abc123def456",
    "state": "completed",
    "platform": "twitter",
    "tool": "createTweet",
    "accountName": "my-twitter",
    "createdAt": "2024-01-15T10:30:00Z",
    "startedAt": "2024-01-15T10:30:05Z",
    "completedAt": "2024-01-15T10:30:15Z",
    "duration": 10000,
    "result": {
      "success": true,
      "output": "Tweet posted successfully",
      "tweetUrl": "https://x.com/username/status/1234567890"
    }
  }
}

Response (Failed):

json
{
  "success": true,
  "data": {
    "taskId": "task_abc123def456",
    "state": "failed",
    "platform": "twitter",
    "tool": "createTweet",
    "accountName": "my-twitter",
    "createdAt": "2024-01-15T10:30:00Z",
    "startedAt": "2024-01-15T10:30:05Z",
    "failedAt": "2024-01-15T10:30:12Z",
    "error": {
      "code": "RATE_LIMITED",
      "message": "Twitter rate limit exceeded. Try again in 15 minutes.",
      "retryAfter": 900
    }
  }
}

List Tasks

Get a list of your tasks with filtering and pagination.

Endpoint:

GET /api/tasks

Query Parameters:

  • limit (optional) - Items per page (default: 50, max: 100)
  • offset (optional) - Number of items to skip (default: 0)
  • platform (optional) - Filter by platform: twitter, xueqiu, eastmoney, tonghuashun
  • action (optional) - Filter by action name: createTweet, likeTweet, post, etc.
  • status (optional) - Filter by status: pending, processing, completed, failed, timeout
  • success (optional) - Filter by success state: true (completed only), false (non-completed)
  • accountName (optional) - Filter by account name
  • accountId (optional) - Filter by account ID
  • execution_engine (optional) - Filter by execution engine: lite, full
  • startDate (optional) - Filter by creation date (ISO 8601 format)
  • endDate (optional) - Filter by creation date (ISO 8601 format)

Example:

bash
# Get recent completed tasks
curl "https://api.browserman.run/api/tasks?status=completed&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get successful tasks only
curl "https://api.browserman.run/api/tasks?success=true&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get tasks for specific account
curl "https://api.browserman.run/api/tasks?accountName=my-twitter&platform=twitter" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get tasks in date range with pagination
curl "https://api.browserman.run/api/tasks?startDate=2024-01-01&endDate=2024-01-31&limit=50&offset=0" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by platform and action
curl "https://api.browserman.run/api/tasks?platform=twitter&action=createTweet&success=true" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "success": true,
  "data": {
    "tasks": [
      {
        "id": "task_abc123",
        "status": "completed",
        "platform": "twitter",
        "action": "createTweet",
        "execution_engine": "lite",
        "params": {
          "text": "Testing Browserman API! 🚀"
        },
        "data": {
          "tweetId": "1234567890"
        },
        "created_at": "2024-01-15T10:30:00Z",
        "started_at": "2024-01-15T10:30:02Z",
        "completed_at": "2024-01-15T10:30:15Z",
        "duration_ms": 13000,
        "platform_account_id": "acc_xyz789"
      },
      {
        "id": "task_def456",
        "status": "completed",
        "platform": "xueqiu",
        "action": "post",
        "execution_engine": "full",
        "params": {
          "text": "今日市场分析"
        },
        "created_at": "2024-01-15T09:15:00Z",
        "completed_at": "2024-01-15T09:15:20Z",
        "duration_ms": 20000,
        "platform_account_id": "acc_abc123"
      }
    ],
    "total": 150,
    "limit": 50,
    "offset": 0,
    "filters": {
      "platform": null,
      "action": null,
      "status": null,
      "success": null,
      "execution_engine": null,
      "accountId": null,
      "accountName": null,
      "startDate": null,
      "endDate": null
    }
  }
}

Cancel Task

Cancel a pending or processing task.

Endpoint:

DELETE /api/tasks/:taskId

Example:

bash
curl -X DELETE https://api.browserman.run/api/tasks/task_abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

json
{
  "success": true,
  "data": {
    "taskId": "task_abc123",
    "state": "cancelled",
    "cancelledAt": "2024-01-15T10:30:30Z"
  }
}

Note: You can only cancel tasks in pending or processing state. Completed or failed tasks cannot be cancelled.

Task Polling

Since tasks are asynchronous, you need to poll for status. Here's a recommended pattern:

JavaScript Example

javascript
async function waitForTask(taskId, maxWaitTime = 300000) {
  const startTime = Date.now();
  const pollInterval = 5000; // 5 seconds

  while (Date.now() - startTime < maxWaitTime) {
    const response = await fetch(
      `https://api.browserman.run/api/tasks/${taskId}`,
      {
        headers: {
          'Authorization': `Bearer ${API_KEY}`
        }
      }
    );

    const { data } = await response.json();

    if (data.state === 'completed') {
      return data.result;
    } else if (data.state === 'failed') {
      throw new Error(data.error.message);
    } else if (data.state === 'timeout') {
      throw new Error('Task timeout');
    } else if (data.state === 'cancelled') {
      throw new Error('Task cancelled');
    }

    // Still pending or processing, wait and retry
    await sleep(pollInterval);
  }

  throw new Error('Polling timeout');
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// Usage
try {
  const task = await createTask({...});
  const result = await waitForTask(task.taskId);
  console.log('Success:', result);
} catch (error) {
  console.error('Error:', error.message);
}

Python Example

python
import time
import requests

def wait_for_task(task_id, max_wait_time=300):
    start_time = time.time()
    poll_interval = 5  # seconds

    while time.time() - start_time < max_wait_time:
        response = requests.get(
            f'https://api.browserman.run/api/tasks/{task_id}',
            headers={'Authorization': f'Bearer {API_KEY}'}
        )

        data = response.json()['data']

        if data['state'] == 'completed':
            return data['result']
        elif data['state'] == 'failed':
            raise Exception(data['error']['message'])
        elif data['state'] in ['timeout', 'cancelled']:
            raise Exception(f"Task {data['state']}")

        time.sleep(poll_interval)

    raise Exception('Polling timeout')

# Usage
try:
    task = create_task({...})
    result = wait_for_task(task['taskId'])
    print('Success:', result)
except Exception as e:
    print('Error:', str(e))

Webhooks

Instead of polling, you can configure webhooks to receive notifications when tasks complete.

Configure Webhook

Endpoint:

POST /api/webhooks

Request:

json
{
  "url": "https://your-server.com/webhook",
  "events": ["task.completed", "task.failed"],
  "secret": "your-webhook-secret"
}

Webhook Payload

When a task completes, Browserman will POST to your webhook URL:

json
{
  "event": "task.completed",
  "taskId": "task_abc123",
  "timestamp": "2024-01-15T10:30:15Z",
  "data": {
    "state": "completed",
    "platform": "twitter",
    "tool": "createTweet",
    "accountName": "my-twitter",
    "result": {
      "success": true,
      "output": "Tweet posted successfully"
    }
  },
  "signature": "sha256=..."
}

Verify Webhook Signature

Verify the webhook signature to ensure authenticity:

javascript
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-browserman-signature'];

  if (!verifyWebhook(req.body, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const { event, taskId, data } = req.body;

  if (event === 'task.completed') {
    console.log('Task completed:', taskId, data.result);
  } else if (event === 'task.failed') {
    console.error('Task failed:', taskId, data.error);
  }

  res.status(200).send('OK');
});

Task Timeouts

Tasks have maximum execution times:

  • Lite mode: 2 minutes default, 5 minutes max
  • Full mode: 5 minutes default, 10 minutes max

If a task exceeds its timeout, it enters the timeout state.

You can specify custom timeouts (within limits):

json
{
  "platform": "twitter",
  "tool": "createTweet",
  "accountName": "my-twitter",
  "timeout": 120000,
  "parameters": {
    "text": "Hello World!"
  }
}

Timeout is in milliseconds.

Error Handling

Common Error Codes

CodeDescriptionRecommended Action
ACCOUNT_NOT_FOUNDAccount doesn't existCheck account name and platform
INVALID_PARAMETERSInvalid tool parametersValidate request body
RATE_LIMITEDPlatform rate limit hitWait for retryAfter seconds
TIMEOUTTask execution timeoutRetry or use full mode
PLATFORM_ERRORPlatform-specific errorCheck error details
AUTHENTICATION_FAILEDAccount auth failedReconnect account
UNAUTHORIZEDInvalid API keyCheck API key

Retry Logic

Implement retry logic with exponential backoff:

javascript
async function retryTask(params, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const task = await createTask(params);
      return await waitForTask(task.taskId);
    } catch (error) {
      if (error.code === 'RATE_LIMITED' && i < maxRetries - 1) {
        const waitTime = error.retryAfter * 1000 || Math.pow(2, i) * 1000;
        await sleep(waitTime);
        continue;
      }
      throw error;
    }
  }
}

Best Practices

1. Always Check Task Status

Never assume a task succeeded. Always check the final state:

javascript
const task = await createTask(params);
const result = await waitForTask(task.taskId);

if (result.success) {
  console.log('Task succeeded:', result.output);
} else {
  console.error('Task failed:', result.error);
}

2. Handle Rate Limits Gracefully

javascript
try {
  await createTask(params);
} catch (error) {
  if (error.code === 'RATE_LIMITED') {
    // Wait and retry
    await sleep(error.retryAfter * 1000);
    return retryTask(params);
  }
  throw error;
}

3. Use Appropriate Polling Intervals

Don't poll too frequently:

javascript
// Good: 5-10 second intervals
const pollInterval = 5000;

// Bad: Too frequent
const pollInterval = 500;

4. Set Reasonable Timeouts

Don't wait forever for tasks:

javascript
// Set a reasonable max wait time
const result = await waitForTask(taskId, 300000); // 5 minutes

5. Log Task IDs

Always log task IDs for debugging:

javascript
const task = await createTask(params);
console.log('Task created:', task.taskId);

// Later you can query this task
const status = await getTaskStatus(task.taskId);

Next Steps