Back to home

API Reference

Complete reference for the BulkAPIs REST API. All endpoints use JSON request/response bodies and require API key authentication.

Base URL: https://bulkapis.com/api/v1

Authentication

All API requests require a Bearer token in the Authorization header:

Authorization: Bearer bulk_ak_your_api_key_here

Create API keys in the dashboard. Keys are shown once on creation โ€” store them securely. All keys are prefixed with bulk_ak_ and are SHA-256 hashed before storage.

Response Format

All responses follow a consistent envelope:

Success

{
  "success": true,
  "data": { ... }
}

Error

{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "...",
    "retryAfter": "2026-..."
  }
}

Plan Limits

BulkAPIs uses an annual membership model. Each plan includes a yearly API call quota. Social features (DMs, posts, account management) require a Social Accounts add-on ($50/mo per 50 accounts).

PlanAnnual API CallsSocial Features
Base ($100/yr)3,000Requires add-on
Growth ($1,000/yr)30,000Requires add-on
Scale ($5,000/yr)250,000Requires add-on

When you exceed your plan limit, API calls return a 403 with code API_CALLS_EXCEEDED. Upgrade your membership to increase your quota.

Quick Start

Step 1: Sign up and subscribe to a membership plan

Step 2: Add a Social Accounts pack and connect your X account via OAuth

Step 3: Create an API key in the dashboard

Step 4: Send your first API call

curl -X POST https://bulkapis.com/api/v1/dm/send \
  -H "Authorization: Bearer bulk_ak_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "your_account_id",
    "recipientUserId": "target_x_user_id",
    "text": "Hello from BulkAPIs!"
  }'

Endpoints

Accounts

GET/api/v1/accounts
GET/api/v1/accounts/:accountId
DELETE/api/v1/accounts/:accountId
GET/api/v1/accounts/:accountId/health

DMs (Direct Messages)

POST/api/v1/dm/send

Conversations

GET/api/v1/conversations?accountId=
GET/api/v1/conversations/:conversationId?accountId=
GET/api/v1/conversations/:conversationId/messages?accountId=
POST/api/v1/conversations/:conversationId/messages

Posts

GET/api/v1/posts?accountId=
POST/api/v1/posts
GET/api/v1/posts/:postId?accountId=
DELETE/api/v1/posts/:postId?accountId=

Comments

GET/api/v1/comments?accountId=&postId=
GET/api/v1/comments/:postId?accountId=
POST/api/v1/comments/:postId

Webhooks

GET/api/v1/webhooks
POST/api/v1/webhooks
GET/api/v1/webhooks/:webhookId
PUT/api/v1/webhooks/:webhookId
DELETE/api/v1/webhooks/:webhookId

API Keys

GET/api/v1/api-keys
POST/api/v1/api-keys
DELETE/api/v1/api-keys?id=

Usage

GET/api/v1/usage?from=&to=

POST /api/v1/dm/send

Send a DM to any X/Twitter user. This is the core feature โ€” most providers cannot initiate new DM conversations. Requires Social Accounts add-on.

Request Body

{
  "accountId": "string",          // Your connected account ID
  "recipientUserId": "string",    // X user ID of the recipient
  "text": "string"                // Message content (max 10,000 chars)
}

Response (202 Accepted)

{
  "success": true,
  "data": {
    "jobId": "abc123",
    "status": "queued",
    "message": "DM queued for delivery"
  }
}

DMs are processed asynchronously via a job queue. Set up a webhook for dm.sent and dm.failed events to track delivery status.

POST /api/v1/posts

Create a new post (tweet) on X/Twitter via a connected account. Requires Social Accounts add-on.

Request Body

{
  "accountId": "string",      // Your connected account ID
  "text": "string"            // Post content (max 280 chars for tweets)
}

Response (202 Accepted)

{
  "success": true,
  "data": {
    "jobId": "def456",
    "status": "queued",
    "message": "Post queued for publishing"
  }
}

Example

curl -X POST https://bulkapis.com/api/v1/posts \
  -H "Authorization: Bearer bulk_ak_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "acc_xxx",
    "text": "Hello world from BulkAPIs! ๐Ÿš€"
  }'

GET /api/v1/accounts

List all connected social media accounts for the authenticated user.

Response (200 OK)

{
  "success": true,
  "data": [
    {
      "id": "acc_xxx",
      "platform": "x",
      "platformUserId": "1234567890",
      "username": "johndoe",
      "displayName": "John Doe",
      "isActive": true,
      "needsReauth": false,
      "createdAt": "2026-01-15T10:30:00Z"
    }
  ]
}

Example

curl https://bulkapis.com/api/v1/accounts \
  -H "Authorization: Bearer bulk_ak_your_key"

POST /api/v1/webhooks

Create a new webhook endpoint to receive real-time event notifications.

Request Body

{
  "name": "string",             // Descriptive name
  "url": "string",              // HTTPS endpoint URL
  "secret": "string",           // (optional) HMAC-SHA256 signing secret
  "events": ["string"],         // Array of event types to subscribe to
  "isActive": true              // (optional) defaults to true
}

Response (201 Created)

{
  "success": true,
  "data": {
    "id": "wh_xxx",
    "name": "Production Webhook",
    "url": "https://example.com/webhooks",
    "events": ["dm.received", "dm.sent"],
    "isActive": true,
    "createdAt": "2026-01-15T10:30:00Z"
  }
}

Example

curl -X POST https://bulkapis.com/api/v1/webhooks \
  -H "Authorization: Bearer bulk_ak_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Webhook",
    "url": "https://example.com/webhooks",
    "secret": "whsec_my_secret",
    "events": ["dm.received", "dm.sent", "dm.failed"]
  }'

Webhook Events

Configure webhooks to receive real-time event notifications. All payloads are signed with HMAC-SHA256 using your webhook secret.

Signature Verification

// Verify the X-BulkAPIs-Signature header
const crypto = require('crypto');
const signature = crypto
  .createHmac('sha256', webhookSecret)
  .update(rawBody)
  .digest('hex');
const isValid = signature === request.headers['x-bulkapis-signature'];

Delivery

Webhooks are delivered with automatic retries (up to 5 attempts) using exponential backoff. Failed deliveries after all retries are moved to a dead letter queue. Expect delivery within seconds of the event.

EventDescription
dm.receivedA DM was received on a connected account
dm.sentA DM was successfully sent
dm.failedA DM failed to send after retries
post.publishedA post was successfully published
post.deletedA post was deleted
comment.receivedA comment/reply was received on a post

Payload Format

{
  "event": "dm.received",
  "timestamp": "2026-02-22T01:00:00Z",
  "data": {
    "accountId": "acc_xxx",
    "conversationId": "1234-5678",
    "messageId": "msg_xxx",
    "senderId": "9876543210",
    "senderUsername": "johndoe",
    "text": "Hey, I commented on your post!",
    "createdAt": "2026-02-22T01:00:00Z"
  }
}

Headers Sent

Content-Type: application/json
X-BulkAPIs-Signature: <hmac-sha256-hex>
X-BulkAPIs-Event: dm.received
X-BulkAPIs-Delivery-Id: <uuid>
X-BulkAPIs-Timestamp: <iso-8601>

Rate Limits

Rate limits are applied per connected account for platform-specific actions and per API key for general requests. Rate-limited responses include a Retry-After header.

EndpointLimit
DM Send180 / 15 min per account
DM Read100 / 15 min per account
DM Events15 / 15 min per account
Post Create200 / 15 min per account
API Requests60 / min per API key

Error Codes

CodeStatusDescription
UNAUTHORIZED401Missing or invalid API key
FORBIDDEN403API key does not have access, or plan limit exceeded
NOT_FOUND404Resource not found
VALIDATION_ERROR400Request body failed validation
RATE_LIMITED429Too many requests โ€” check Retry-After header
ACCOUNT_NEEDS_REAUTH400Connected account needs re-authorization
PLAN_LIMIT403Membership plan limit reached (upgrade required)
NO_SOCIAL_PACK403Social features require a Social Accounts add-on
API_CALLS_EXCEEDED403Annual API call quota exhausted
SOCIAL_ACCOUNTS_EXCEEDED403Connected account limit reached (add another pack)
PLATFORM_ERROR502Upstream platform API error
INTERNAL_ERROR500Unexpected server error

Need help? Dashboard ยท Home