API Documentation
The Social Crow API lets you place and manage orders programmatically — no web interface needed. It is designed for resellers and developers who want to automate their workflow or build tooling on top of Social Crow's services.
npm install @socialcrow/sdkRequires Node.js 18+. See the SDK section for usage examples.
Authentication
Every request must include your API key in the Authorization header as a Bearer token. Requests without a valid key receive a 401 response with error code UNAUTHORIZED.
Generate or regenerate your key at any time from the API settings page. Regenerating immediately invalidates the previous key.
curl https://www.socialcrow.co/api/v1/balance \
-H "Authorization: Bearer sk_live_YOUR_KEY"Quick Start
Three steps to place your first order: check your balance, find a service, and submit the order.
# 1. Check your balance
curl https://www.socialcrow.co/api/v1/balance \
-H "Authorization: Bearer sk_live_YOUR_KEY"
# 2. List available services
curl https://www.socialcrow.co/api/v1/services \
-H "Authorization: Bearer sk_live_YOUR_KEY"
# 3. Place an order
curl -X POST https://www.socialcrow.co/api/v1/orders \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"serviceId":"1234","link":"https://instagram.com/username","quantity":1000}'TypeScript SDK
The official TypeScript SDK wraps the REST API with full types and a Result pattern: every method returns Result<T> instead of throwing. You never need try/catch.
result.oktrue — order succeeded
result.data is available and fully typed. TypeScript will not let you access result.error in this branch.
!result.okfalse — something went wrong
result.error.code is a typed union of all possible error codes — your IDE autocompletes every value. result.error.message is a human-readable string with context. No exceptions are thrown.
npm install @socialcrow/sdkfetch support.# The SDK wraps the REST API — use the TypeScript tab for SDK usage.Endpoints
/servicesList Services
Returns all active services with their IDs, names, categories, and customer-facing pricing. Cache this response — services change infrequently.
Response fields
idstringnamestringcategorystringtypestringminnumbermaxnumberratenumberdripfeedbooleanrefillbooleancurl https://www.socialcrow.co/api/v1/services \
-H "Authorization: Bearer sk_live_YOUR_KEY"/ordersCreate Order
Places a single order using your account balance. Returns an orderId, the charge deducted from your balance, and the currency on success (HTTP 201). Each call creates exactly one order for one service.
Response fields (HTTP 201)
orderIdUnique short ID for the order. Use with GET /orders/:id to track status.chargeAmount deducted from your account balance for this order, as a decimal number.currencyCurrency of the charge (always "USD").Required fields by service type
type: "default"serviceId link quantitytype contains "comment"serviceId link quantity comments requireddripfeed: trueany of the above, plus runs interval (optional)type field from GET /services before placing an order. If type.toLowerCase().includes("comment") is true, you must include a comments array — the API will return MISSING_COMMENTS otherwise.| Parameter | Type | Required | Description |
|---|---|---|---|
| serviceId | string | required | Service ID from GET /services |
| link | string | required | Target URL or username |
| quantity | integer | required | Number of units — must be within the service's min/max |
| comments | string[] | optional | Array of comment strings. Required when service.type contains "comment" (e.g. "custom comments"). Omit for all other service types. |
| runs | integer | optional | Number of delivery runs. Only valid when service.dripfeed is true. |
| interval | integer | optional | Minutes between runs. Required when runs is provided. |
curl -X POST https://www.socialcrow.co/api/v1/orders \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"serviceId": "1234",
"link": "https://instagram.com/username",
"quantity": 1000
}'
# Response (HTTP 201)
# { "data": { "orderId": "V1StGXR8", "charge": 1.25, "currency": "USD" } }/quoteGet Quote
Get the exact charge amount for an order without placing it. Uses the same pricing logic as order creation — including rounding and minimums — so the returned amount matches what would be deducted from your balance. Useful when service rates are per 1,000 units but you order fewer (e.g. 100 followers at $6.24/1,000); the actual charge may differ from a naive rate × quantity ÷ 1000.
Response fields (HTTP 200)
serviceIdService ID that was quoted (echoed from the request).quantityQuantity that was quoted (echoed from the request).chargeAmount that would be deducted from your account balance, as a decimal number.currencyCurrency of the charge (always "USD").Same validation as Create Order: quantity must be within the service's min/max; drip-feed and comment-type services require their respective fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
| serviceId | string | required | Service ID from GET /services |
| quantity | integer | required | Number of units — must be within the service's min/max |
| comments | string[] | optional | Required when service.type contains "comment" |
| runs | integer | optional | Number of delivery runs. Only valid when service.dripfeed is true. |
| interval | integer | optional | Minutes between runs. Required when runs is provided. |
curl -X POST https://www.socialcrow.co/api/v1/quote \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"serviceId":"1234","quantity":100}'
# Response (HTTP 200)
# { "data": { "serviceId": "1234", "quantity": 100, "charge": 0.63, "currency": "USD" } }/orders/:idGet Order Status
Returns the current status of a single order, synced fresh from the external panel on each call. Only orders placed via API (tied to your account) are accessible.
Status values
curl https://www.socialcrow.co/api/v1/orders/V1StGXR8 \
-H "Authorization: Bearer sk_live_YOUR_KEY"/orders/bulkBulk Order Status
Check the status of up to 100 orders in a single request. Returns a map of orderId → status. Order IDs that don't belong to your account return an error entry rather than a 404 — useful for batch reconciliation.
| Parameter | Type | Required | Description |
|---|---|---|---|
| orders | string[] | required | Array of order IDs (orderIdShort). Maximum 100. |
curl -X POST https://www.socialcrow.co/api/v1/orders/bulk \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"orders": ["V1StGXR8", "Xk9pLqM2", "unknown_id"]}'/ordersList Orders
Returns a paginated list of all orders placed via the API for your account, sorted newest first.
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | integer | optional | Page number (default: 1). 20 orders per page. |
# First page
curl "https://www.socialcrow.co/api/v1/orders" \
-H "Authorization: Bearer sk_live_YOUR_KEY"
# Page 2
curl "https://www.socialcrow.co/api/v1/orders?page=2" \
-H "Authorization: Bearer sk_live_YOUR_KEY"/balanceGet Balance
Returns the current account balance in USD. The value is accurate to 4 decimal places with no rounding. Balances are always positive — orders are rejected if balance is insufficient.
curl https://www.socialcrow.co/api/v1/balance \
-H "Authorization: Bearer sk_live_YOUR_KEY"
# Response
# { "data": { "balance": "12.3400", "currency": "USD" } }/refillsCreate Refill Request
Submits a refill request for a delivered order. Social Crow offers a 30-day refill guarantee — if the count on a delivered order drops, you can request a top-up here.
refill: true on the service from GET /services). If the service does not support automatic refills, you will receive a REFILL_NOT_ELIGIBLE error — contact support for a manual refill.DELIVERED before a refill can be requested. If a refill is already pending for the order, subsequent requests will return REFILL_ALREADY_PENDING.| Parameter | Type | Required | Description |
|---|---|---|---|
| orderId | string | required | The order ID (orderIdShort) returned when the order was created. |
Response fields
refillIdstringorderIdstringstatusstringcurl -X POST https://www.socialcrow.co/api/v1/refills \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"orderId":"ABC123456789DE"}'/refills/:idGet Refill Status
Returns the current status of a refill request for a given order. The :id path parameter is the orderId returned when the order was created.
Refill status values
Response fields
refillIdstringorderIdstringstatusstringrequestCountnumbercreatedAtstringlastRefilledAtstring | nullcurl https://www.socialcrow.co/api/v1/refills/ABC123456789DE \
-H "Authorization: Bearer sk_live_YOUR_KEY"/refills/bulkBulk Create Refills
Submit refill requests for up to 100 orders in a single call. Returns a map of orderId → result. Orders that are ineligible or not found return an error entry in the map rather than a 4xx response — allowing you to process the full batch in one pass.
| Parameter | Type | Required | Description |
|---|---|---|---|
| orders | string[] | required | Array of order IDs (orderIdShort). Maximum 100. |
curl -X POST https://www.socialcrow.co/api/v1/refills/bulk \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"orders":["ABC123456789DE","ord_def456"]}'/refills/statusBulk Refill Status
Check the refill status of up to 100 orders in a single request. Returns a map of orderId → refill status. Orders with no refill request, or that don't belong to your account, return an error entry rather than a 404.
| Parameter | Type | Required | Description |
|---|---|---|---|
| orders | string[] | required | Array of order IDs (orderIdShort). Maximum 100. |
curl -X POST https://www.socialcrow.co/api/v1/refills/status \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"orders":["ABC123456789DE","ord_def456"]}'Error Handling
The API uses a consistent, predictable error system across every endpoint. Whether you use the REST API directly or the TypeScript SDK, errors always have the same shape and the same typed codes — making it straightforward to handle each case explicitly in your code.
Response shape
Every response is either a success envelope or an error envelope — never both. HTTP status codes reflect the category of error.
Success — HTTP 200 / 201
{ "data": { ... } }Error — HTTP 4xx / 5xx
{ "error": { "code": "INSUFFICIENT_BALANCE", "message": "Your balance is $2.40 but this order costs $5.00" } }error.code
A stable, machine-readable string constant. Use this in switch statements and conditionals. It will never change between API versions.
error.message
A human-readable string with contextual detail — e.g. the exact min/max for INVALID_QUANTITY, or your current balance for INSUFFICIENT_BALANCE. Safe to surface to users.
Handling errors in your code
The TypeScript SDK makes error handling completely explicit via the Result pattern — check result.ok first, then branch on result.error.code. Your IDE autocompletes every possible code value. For other languages, check for the error key in the JSON response before accessing data.
# All responses are JSON — check for the "error" key before using "data".
response=$(curl -s -X POST https://www.socialcrow.co/api/v1/orders \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"serviceId":"1234","link":"https://instagram.com/u","quantity":1000}')
if echo "$response" | python3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if 'error' in d else 1)" 2>/dev/null; then
code=$(echo "$response" | python3 -c "import sys,json; print(json.load(sys.stdin)['error']['code'])")
msg=$(echo "$response" | python3 -c "import sys,json; print(json.load(sys.stdin)['error']['message'])")
echo "Error [$code]: $msg"
else
order_id=$(echo "$response" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['orderId'])")
echo "Order placed: $order_id"
fiError codes
| Code | HTTP | When it occurs |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid API key |
SERVICE_NOT_FOUND | 404 | serviceId does not exist |
SERVICE_INACTIVE | 400 | Service exists but is currently disabled |
INVALID_QUANTITY | 400 | quantity is below min or above max for the service |
INVALID_LINK | 400 | link is missing or empty |
MISSING_COMMENTS | 400 | Comment-type service ordered without comments |
DRIPFEED_NOT_SUPPORTED | 400 | runs or interval sent for a non-drip-feed service |
INVALID_DRIPFEED_PARAMS | 400 | runs or interval is missing, zero, or non-integer |
INSUFFICIENT_BALANCE | 402 | Account balance is too low to cover the order |
ORDER_NOT_FOUND | 404 | Order ID does not exist or belongs to a different account |
TOO_MANY_ORDERS | 400 | Bulk request exceeds 100 order IDs |
INVALID_REQUEST | 400 | Request body is malformed or a required field is missing |
RATE_LIMITED | 429 | Services endpoint exceeded 10 requests/minute |
METHOD_NOT_ALLOWED | 405 | Wrong HTTP method used (e.g. POST on a GET-only endpoint) |
INTERNAL_ERROR | 500 | Unexpected server error |
REFILL_NOT_ELIGIBLE | 400 | Refill requested for a service where the external panel does not support automatic refills — contact support |
ORDER_NOT_DELIVERED | 400 | Refill requested but the order has not yet reached DELIVERED status |
REFILL_ALREADY_PENDING | 400 | A refill is already pending for this order — wait for it to complete before requesting another |
NO_PANEL_ORDER | 400 | No eligible external panel order found for this order — contact support |
REFILL_FAILED | 400 | The external panel rejected the refill request — the panel's error message is included in the response |