← Back Request Access

CloutAPI Documentation

CloutAPI provides a RESTful interface for operators building social growth platforms. This documentation covers authentication, order management, and webhook integration.

⚠️ Service Abstraction Notice
Service IDs represent abstract categories. Fulfillment sources may change while maintaining consistent APIs. Delivery speed, refill behavior, and outcomes may vary. CloutAPI does not guarantee delivery or specific results.

Base URL

https://api.clout.llc/v1

Quick Start

curl https://api.clout.llc/v1/orders \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: your_unique_key" \ -d '{"service":"ig_followers_hq","target":"@username","quantity":1000}'

Always include an Idempotency-Key header for POST requests to prevent duplicate orders on retry.

Authentication

Authenticate via the Authorization header using Bearer token format:

Authorization: Bearer clout_live_sk_xxxxxxxxxxxxx
💡 Test vs Live Keys
Test keys (clout_test_sk_) return simulated responses without placing real orders or deducting balance. Live keys (clout_live_sk_) place actual orders and deduct from your account balance. Test mode webhooks are still delivered for integration testing.

Service Abstraction

⚠️ Critical: Service IDs are Abstract Identifiers
Service IDs (e.g., ig_followers_hq) represent abstract service categories, not specific fulfillment sources. Clout may route orders to different upstream providers while maintaining the same service ID and response format.

What This Means

AspectMay VaryConsistent
Fulfillment sourceYes — routing changes based on provider health
Delivery speedYes — 1-72 hours typical range
Refill behaviorYes — depends on provider
API response formatYes — always consistent
Webhook eventsYes — always delivered
Order ID formatYes — always ord_ prefix
Billing/ledgerYes — always accurate

Implications for Your Integration

Do not rely on specific delivery times or provider behavior. Build your integration to handle:

  • Variable delivery windows (check status via webhooks or polling)
  • Partial completions (order.partial status)
  • Order failures (order.failed status with refund)
No Guarantees
CloutAPI does not guarantee delivery speed, completion rates, or specific outcomes. Service quality depends on upstream providers which Clout monitors but does not control.

Idempotency

To safely retry requests without risk of duplicate orders, include an Idempotency-Key header:

Idempotency-Key: ord_unique_key_12345

Keys are stored for 24 hours. If you retry a request with the same key, you'll receive the original response.

Best Practices

ScenarioRecommendation
Network timeoutRetry with same idempotency key
5xx errorsSafe to retry with exponential backoff
4xx errorsDo not retry (client error)

Rate Limits

API requests are rate limited per API key and per IP address.

TierRequests/minBurst
Starter6010
Growth30050
EnterpriseCustomCustom

Rate limit headers are included in every response:

X-RateLimit-Limit: 300 X-RateLimit-Remaining: 299 X-RateLimit-Reset: 1705071660

Errors

Standard HTTP codes indicate success or failure. All errors include a structured response body with a request_id for support reference.

CodeDescriptionRetryable
200Success
400Bad Request — Invalid parametersNo
401Unauthorized — Invalid or missing API keyNo
402Payment Required — Insufficient balanceNo (add funds first)
404Not Found — Resource doesn't existNo
409Conflict — Idempotency key already used with different paramsNo (use new key)
422Unprocessable — Valid syntax but cannot process (e.g., invalid target)No
429Too Many Requests — Rate limit exceededYes (after backoff)
500Server Error — Internal errorYes (with idempotency key)
502Bad Gateway — Provider unreachableYes (with idempotency key)
503Service Unavailable — Temporarily overloadedYes (after backoff)

Error Response

{ "error": { "type": "invalid_request_error", "code": "insufficient_balance", "message": "Insufficient balance for this order. Required: $24.99, Available: $10.00", "param": null, "request_id": "req_1a2b3c4d5e", "retryable": false } }

Error Types

TypeRetryableDescriptionAction
invalid_request_errorNoInvalid parameters or malformed requestFix request and retry
authentication_errorNoInvalid API key or permissionsCheck API key
rate_limit_errorYesToo many requestsWait for X-RateLimit-Reset
api_errorYesServer-side issueRetry with same idempotency key
provider_errorYesUpstream provider issueRetry with same idempotency key
Always Include request_id in Support Requests
When contacting support about an error, include the request_id from the error response. This allows us to trace the exact request in our logs.

Webhooks

Receive real-time order status updates. Configure your endpoint URL in the Dashboard.

Events

EventDescriptionFinal State
order.createdOrder accepted and queuedNo
order.processingOrder sent to providerNo
order.completedOrder fulfilled (check delivered count)Yes
order.partialPartially fulfilled (check delivered vs quantity)Yes
order.failedOrder failed (balance refunded)Yes
⚠️ Always Verify Delivered Count
Even for order.completed events, always check the delivered field in the webhook payload. The delivered count may differ from the requested quantity.

Webhook Signatures

All webhooks include a signature header for verification:

Clout-Signature: t=1705071600,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Verify the signature using HMAC-SHA256 with your webhook secret:

const crypto = require('crypto'); function verifySignature(payload, signature, secret) { const [t, v1] = signature.split(',').map(p => p.split('=')[1]); const expected = crypto .createHmac('sha256', secret) .update(t + '.' + payload) .digest('hex'); return v1 === expected; }

Retry Policy

Failed webhook deliveries are retried with exponential backoff: 1min, 5min, 30min, 2hr, 24hr. After 5 failures, the webhook is disabled and you'll receive an email notification.

Create Order

POST/v1/orders

Creates a new order. Always include an Idempotency-Key header to prevent duplicate orders on retry.

Request Headers

HeaderDescription
AuthorizationrequiredBearer token: Bearer clout_live_sk_xxx
Content-Typerequiredapplication/json
Idempotency-KeyrecommendedUnique key for this request (max 255 chars)

Request Body

ParameterTypeDescription
servicerequiredstringService ID (e.g., ig_followers_hq)
targetrequiredstringTarget URL or username
quantityrequiredintegerNumber of units (within service min/max)
metadataoptionalobjectCustom key-value data (max 10 keys)

Response

{ "id": "ord_7x9K2mN4pQ8r", "object": "order", "status": "pending", "service": "ig_followers_hq", "target": "@techstartup", "quantity": 1000, "start_count": 15420, "delivered": 0, "cost": 24.99, "currency": "usd", "created_at": "2025-01-12T15:00:00Z" }

Response Fields

FieldTypeDescription
idstringUnique order identifier
statusstringOne of: pending, processing, completed, partial, failed, canceled
start_countinteger|nullTarget's count at order creation (if available)
deliveredintegerUnits delivered so far
costnumberAmount charged to your balance
⚠️ Service Abstraction Reminder
The same service ID may be fulfilled by different providers. Delivery speed and behavior may vary. Do not rely on specific timing.

Get Order

GET/v1/orders/:id

Retrieves order details.

List Orders

GET/v1/orders

Returns paginated orders, most recent first.

Query Parameters

ParameterDescription
limitoptionalResults per page (1-100)
statusoptionalFilter by status
serviceoptionalFilter by service

Cancel Order

POST/v1/orders/:id/cancel

Cancels a pending order. Only orders with status: pending can be cancelled. Orders that have started processing cannot be cancelled.

Response

{ "id": "ord_7x9K2mN4pQ8r", "status": "canceled", "refunded": true, "refund_amount": 24.99 }

Errors

CodeMessageReason
400Order cannot be canceledOrder is not in pending status
404Order not foundInvalid order ID or not your order

List Services

GET/v1/services

Returns available services with current pricing.

Response

{ "data": [{ "id": "ig_followers_hq", "name": "Instagram Followers - High Quality", "platform": "instagram", "type": "followers", "cost_per_1k": 24.99, "min_quantity": 100, "max_quantity": 100000, "refill_days": 30, "status": "active" }] }

Response Fields

FieldTypeDescription
idstringService ID to use in order creation
namestringHuman-readable description (for reference only)
cost_per_1knumberYour cost per 1,000 units
refill_daysintegerRefill window in days (0 = no refill)
statusstringactive or degraded
⚠️ Service IDs are Abstract
The name field is for reference only. Service characteristics may vary as fulfillment is routed across multiple providers. Do not display service names to end users as product guarantees.

Get Balance

GET/v1/balance

Returns your account balance calculated from the immutable ledger.

{ "available": 1247.50, "pending": 124.00, "currency": "usd" }

Response Fields

FieldDescription
availableBalance available for new orders
pendingBalance reserved for processing orders

Balance is calculated in real-time from ledger entries. Use GET /v1/ledger (coming soon) to view transaction history.