Send your account API key either in Authorization: Bearer YOUR_API_KEY or as the key request field. Choose one method; the key field works with common reseller panels. Keep keys in server-side environment variables and rotate them from Account.
All actions use POST https://smm.africa/api/v3. Supported bodies: application/json, application/x-www-form-urlencoded, and multipart/form-data with text fields only. Responses are JSON. The action field selects the operation.
Why are my customer payments separate from my SMM.Africa wallet?
Your customer pays your business under your own arrangement. Your SMM.Africa wallet pays for the orders you submit here. Collecting a customer payment does not automatically fund that wallet, and a wallet refund does not automatically reimburse your client. Reconcile the two records separately, including fees and any approved customer refund.
Start with the API authentication and balance examples, then review the service, target format, limits, and price. Use a target you control and a quantity within the stated limits. The add action spends wallet balance. Save the returned order ID and check its status. Read the current API documentation before choosing a retry strategy.
Open this answerShould I send another API order if the first request times out?
First check whether the original request created an order. A timeout can leave the outcome uncertain even when processing succeeded. Preserve the request reference and any order ID, and use the documented idempotency mechanism where supported. Do not generate a new paid request merely because the first response was missing; contact support if the outcome remains unclear.
Your API key, used to authenticate the request. Required only when Authorization: Bearer is absent.
action
string
Yes
add Use the exact action value shown.
service
integer
Yes
The ID of the service you want to order. Use an ID from the current services response; its type determines the fields below.
link
string
Conditional
The target profile, post, or content URL. Required for the selected service type; supply the target URL.
quantity
integer
Conditional
The quantity you want to order. Must satisfy the selected service's min and max. Omit when its type does not accept quantity.
max_charge
number / decimal string
No
Optional maximum USD charge, including discounts, with up to six decimal places. PRICE_LIMIT_EXCEEDED (409) creates no order or debit. Changing a ceiling changes request intent. Maximum permitted USD charge, with at most six decimal places.
idempotency_key
string
Recommended
Use one unique value per logical order. If the request times out without a response, retry with the same value so the order cannot be charged twice. Persist a unique value per logical order; reuse only with an identical retry payload.
Fields by service type
Select the type returned by services; do not send a separate type field. List values are newline-separated text, including in JSON. The API derives billable quantity for comments, custom lists and packages, then checks service limits.
Service type
Required fields
Optional fields / constraints
Default
link, quantity
Standard target URL and requested quantity.
Package
link
No quantity.
SEO
link, quantity, keywords
Put one keyword on each line.
Custom Comments
link, comments
One comment per line; the comment count is the order quantity.
Custom Comments Package
link, comments
One comment per line; no quantity.
Comment Replies
link, username, comments
username is the comment owner; put one reply per line.
Comment Likes
link, username
username is the comment owner; no quantity.
Mentions
link, quantity, usernames
Put one username per line.
Mentions with Hashtags
link, quantity, usernames, hashtags
Put usernames and hashtags on separate lines.
Mentions Custom List
link, usernames
Put one username per line; no quantity.
Mentions Hashtag
link, quantity, hashtags
Put one hashtag per line.
Mentions User Followers
link, quantity, username
username is the source profile URL to scrape.
Mentions Media Likers
link, quantity, media
media is the source media URL to scrape.
Poll
link, quantity, answer
answer is the exact poll-option text required for the service.
Invites from Groups
link, quantity, groups
Put one group on each line.
Web Traffic
link, quantity, country, device, type_of_traffic
device is mobile or desktop. type_of_traffic is 1 (requires google_keyword), 2 (requires referring_url), or 3.
Optional attribution fields
Parameter
Type
Required
Description & constraints
goal_key
string
No
Optional goal key for guided-growth attribution. Optional attribution metadata.
Your API key, used to authenticate the request. Required only when Authorization: Bearer is absent.
action
string
Yes
status Use the exact action value shown.
order
integer / string
Yes
The SMM Africa order ID returned by add. Use the order ID returned by add for follow-up requests.
orders
array / string
Conditional
For bulk status, send 1–20 IDs as a JSON array or comma-separated form string instead of order. Inspect each item's http_status and retry_after. Use order or orders, never both. Each bulk item has its own http_status.
Check balance, fetch services, select the service type, persist an operation ID, submit the order, save its order ID, then poll status. Prices are USD; rates are per 1,000 units or per package according to service type. Treat IDs as opaque strings. Decimal strings and numeric money fields retain their existing types; charges use six-decimal USD precision.
The Node.js and PHP 3.3 clients persist operation keys and successful responses, honor Retry-After, and stop unresolved mutations before the 24-hour replay window expires. Keep state private, persistent, and separate for each account. Test first with the local sandbox, which has no connection to live wallets or suppliers.
node sandbox.mjs
# Endpoint: http://127.0.0.1:4013/api/v3
# Key: sandbox_test_key (never use a live key)
subscription_create
Create a capped subscription without debiting funds. Use a post-URL service, a positive integer quantity, USD, spending_cap with up to six decimals, max_posts (1–10000), and a persisted idempotency key.
Submit a discovered post URL. The service and quantity come from the subscription. Optional max_charge caps this post in USD. A repeated canonical URL returns its original order, including after cancellation.
Configure one verified HTTPS receiver per account. Requires deployment enablement. Generate a random 32–128 character base64url secret. Verify X-SMM-Signature, then echo the webhook.verify challenge as JSON. Reconfiguration invalidates old pending events.
Read up to 20 deliveries, their payload, attempts, last HTTP status, and next attempt time. Pass after=next_cursor for subsequent pages. History is retained for 30 days.
Queue a delivered or failed event for the same endpoint version. The event ID is preserved. Consumers must deduplicate; replay never repeats an order or wallet mutation.
X-SMM-Signature contains t=UNIX_SECONDS,v1=HEX_HMAC_SHA256. Sign timestamp + "." + the exact raw request body with your secret. Use constant-time comparison and reject timestamps more than five minutes from your clock. Persist each event ID before returning 2xx. Delivery is at least once and may arrive out of order. Events cover account order activity, including website orders. Fetch status for current delivery and refund details; polling remains the reconciliation fallback. Failed delivery retries up to eight times with backoff; redirects are rejected.
Check the HTTP status and the JSON error field. Authentication errors use HTTP 400; API callers are not redirected to login. Log technical errors privately and show customers a neutral message.
Add responses replay for 24 hours. After expiry, the same key can create another order: reconcile first. REQUEST_IN_PROGRESS permits the same request/key after Retry-After. IDEMPOTENCY_CONFLICT requires restoring the original payload. ACTION_OUTCOME_UNCONFIRMED requires support review: never change keys to bypass it. PRICE_LIMIT_EXCEEDED means no debit or order was committed. Log request_id (also X-Request-Id) for support.
HTTP
Error / condition
What to do
400
Invalid API key
Check the key and required fields. Correct the request before retrying.
402
Insufficient balance
Fund the account wallet before submitting the order again.
409
A matching API order request is already being processed
Wait before retrying the identical request with its original idempotency key.
409
This idempotency key was already used for a different API order request
Restore the original payload for a retry. Use a new key only for a new logical order.
415
Unsupported content type
Send JSON, URL-encoded form fields, or multipart text fields.
423
Account suspended (message varies)
Resolve the account restriction with support; do not retry repeatedly.
429
Too many requests. Please slow down and try again shortly.
Wait for the Retry-After interval, then retry with backoff.
500 / 503
Server failure or temporary unavailability (message varies)
Back off. For order submissions, keep the same payload and idempotency key.
Retry an order without charging twice
Create and persist a unique idempotency_key for each logical order before sending add. Replace the example key with your own unique value.
Allow up to 60 seconds for the server request. After 20 seconds, show a pending message to the customer while the backend request continues.
If no response arrives, retry the exact same payload with the same key after a delay. Do not generate a new key. A completed retry replays the response with X-Idempotent-Replay: true.
Once you receive an order ID, save it and use status to track that order. A queued response means accepted for fulfillment, not completed delivery.
Idempotency-Key and X-Idempotency-Key headers are also supported. Without a client key, an order can still be submitted, but retrying after a timeout cannot safely identify the original attempt.
Rate limits
Limits are action-specific and deployment-configurable. On HTTP 429, honor Retry-After (seconds). Without that header, use exponential backoff with jitter, for example 2, 4, 8, then 16 seconds plus a small random delay. Bound retries and surface persistent failures to your operator.
Cache the catalog fetched with POST /api/v3 and action=services. Refresh it periodically and verify current service IDs, rates, and min/max constraints before ordering.
Order lifecycle
Send action=status with order for one ID, or orders for 1–20 IDs. Bulk responses include http_status per item; back off per item using retry_after. As a starting client policy, poll every 30 seconds, then increase the interval for long-running orders; honor rate limits. Stagger requests across orders. Signed order webhooks are available when enabled for the deployment. Keep bulk polling for reconciliation. A stale response never authorizes repeating add.
queued → pending → processing
Active states: continue polling. Orders may skip intermediate states.
completed · partial · refunded · canceled
Terminal states: stop routine delivery polling. Partial means delivery was incomplete; inspect charge and remains. Refill and cancellation requests are subject to service and order eligibility.
unknown
An unrecognized state; do not treat it as success or place a replacement order automatically. Retry status with backoff and contact support if it persists.
Integration notes for production use
Treat the API like infrastructure. These notes cover the things that matter once you are running automated orders, a client panel, or a high-volume storefront.
Shared wallet balance
Direct orders, storefront orders, and API orders all draw from the same wallet balance. Fund it from any channel, use it from any channel.
Secure your key
Never expose the key, API hostname, configured provider name, or raw transport errors in client-side code or storefront messages. Proxy calls through your backend, log technical details privately, and after 20 seconds show customers neutral wording such as: Order submission is taking longer than expected. Check your orders before trying again.
Quick answers
How do I get an API key?
Log in to SMM Africa, open Account, copy your API key, and rotate it from the same place at any time.
Is the API free?
There is no extra API fee. You only pay for services you order. The same wallet funds direct orders, storefront orders, and API orders.
What are the rate limits?
Limits are action-specific and can change. Space bulk calls, batch status polls, and when the API returns 429 wait for the Retry-After interval before retrying.
How should I handle retries?
Send one unique Idempotency-Key header or idempotency_key field for each logical add order. If the request times out, retry the identical payload with the same key so a completed attempt is replayed without another charge.
Is there a webhook?
Status polling is the supported path today. Hit the status action for orders you are watching and cache the result in your own system.
Which countries are supported?
The API is available worldwide, with strong support for African markets and M-Pesa-friendly wallet funding.
API vocabulary
Terms resellers should understand
Reseller API
A server-to-server interface that lets another panel or workflow place and track SMM Africa orders from its own application.
Service catalog
The live list of service IDs, prices, limits, refill support, and cancellation support used before placing an order.
Action
The JSON field that chooses the API operation, such as balance, services, add, status, refill, or cancel.
Wallet-backed ordering
An ordering model where direct, storefront, and API orders all draw from the same funded SMM Africa wallet balance.