EngageGate API

The EngageGate API lets you order social engagement services programmatically. It follows the widely-used SMM-panel V2 protocol, so if you already integrate with other panels the request/response shape will be familiar.

Status: All catalog services are live and orderable — Views, engagement (likes / retweets / bookmarks), and Subscription packages. See Service catalog.


1. Overview

Endpoint POST https://engagegate.app/api/v2
Method POST only
Content-Type application/x-www-form-urlencoded (recommended). application/json is also accepted.
Authentication Your API key, sent either as the key body field or the X-API-Key header.
Action Every request carries an action field selecting the operation (services, balance, topup, add, status, cancel).
Responses Always HTTP 200, even for errors. The body is JSON.
Errors Returned in the body as {"error": "..."}. Never as a non-200 status code.

Because the API always returns HTTP 200, do not branch on the HTTP status code to detect failures. Instead, inspect the JSON body: if it contains an error key, the request failed and the error value is a human-readable message.

The services action is public — it requires no API key and is not rate-limited — so you can inspect the catalog before signing up. Every other action requires a valid API key.

Request shape

POST /api/v2
Content-Type: application/x-www-form-urlencoded

key=YOUR_API_KEY&action=balance

Error envelope

{ "error": "Incorrect API key" }

2. Authentication & keys

  1. Sign in to your EngageGate account and open engagegate.app/account/api.
  2. Mint a new API key. The raw key value is shown exactly once — on creation and on regeneration. Copy and store it securely; it cannot be retrieved again. If you lose it, regenerate the key (which invalidates the old value).
  3. Send the key with every authenticated request, either as:
    • the key body field, or
    • the X-API-Key HTTP header (this takes precedence if both are supplied).

Any authentication failure — missing key, unknown key, disabled key, or a disabled account — returns the same generic message so the response cannot be used to probe which keys exist:

{ "error": "Incorrect API key" }

Sandbox keys (testing)

When minting a key you can flag it as a sandbox key. Sandbox keys behave identically to live keys for every read action, but the add action does not charge your wallet and does not place a real order — it returns a mock, already-completed order so you can build and test your integration end-to-end without spending funds or generating real engagement. See the FAQ for the full sandbox behaviour.


3. Actions

Each action below lists its parameters, a curl example, a Python (requests) example, and an example JSON response.

In the Python examples we use form data (data=...), which is the recommended encoding.


services — list the catalog (public)

Returns the full service catalog as a JSON array. No API key is required and this action is not rate-limited.

Parameters

Name Required Description
action yes services

curl

curl -s https://engagegate.app/api/v2 \
  -d action=services

Python

import requests

resp = requests.post(
    "https://engagegate.app/api/v2",
    data={"action": "services"},
)
print(resp.json())

Example response (array of service objects)

[
  {
    "service": 100,
    "name": "Likes — Standard",
    "type": "Default",
    "category": "Likes",
    "min": 10,
    "max": 1000,
    "refill": false,
    "cancel": true,
    "dripfeed": true,
    "rate": "10.00"
  },
  {
    "service": 200,
    "name": "Views",
    "type": "Default",
    "category": "Views",
    "min": 100,
    "max": 1000000,
    "refill": false,
    "cancel": true,
    "dripfeed": true,
    "rate": "0.18"
  },
  {
    "service": 300,
    "name": "Subscription Starter",
    "type": "Package",
    "category": "Subscription",
    "min": 1,
    "max": 1,
    "refill": false,
    "cancel": false,
    "dripfeed": false,
    "flat_price": "359.00"
  }
]

Field notes

  • service — the integer service id you pass to add and other actions.
  • rate — price per 1,000 units (string, USD) for per-1000 services (Likes, Retweets, Bookmarks, Views).
  • flat_price — a single fixed price (string, USD) for Package services (Subscriptions). These rows carry flat_price instead of rate.
  • min / max — the allowed quantity range.
  • refill is always false — refill is not supported (see refill).
  • The rate shown for Views is dynamic and may change; always read it fresh from services before ordering.

balance — check your wallet balance

Parameters

Name Required Description
key yes Your API key (or send X-API-Key).
action yes balance

curl

curl -s https://engagegate.app/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=balance

Python

import requests

resp = requests.post(
    "https://engagegate.app/api/v2",
    data={"key": "YOUR_API_KEY", "action": "balance"},
)
print(resp.json())

Example response

{ "balance": "123.45", "currency": "USD" }

balance is a string with two decimals. A new account with no wallet yet simply reports "0.00" — that is not an error.


topup — add funds to your wallet

Creates a crypto deposit invoice. Pay the invoice and your wallet is credited automatically once payment is confirmed; you do not need to call back.

Parameters

Name Required Description
key yes Your API key (or send X-API-Key).
action yes topup
amount yes USD amount to deposit. Must be a number greater than 0.

curl

curl -s https://engagegate.app/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=topup \
  -d amount=50

Python

import requests

resp = requests.post(
    "https://engagegate.app/api/v2",
    data={"key": "YOUR_API_KEY", "action": "topup", "amount": "50"},
)
print(resp.json())

Example response

{
  "invoice_url": "https://pay.example.com/invoice/abc123",
  "invoice_id": "abc123"
}

Open invoice_url to complete payment. On an invalid amount the response is {"error": "Invalid amount"}; if invoicing is briefly unavailable it is {"error": "Top-up temporarily unavailable"}.


add — place an order

Places a new order. All catalog services are orderable. Ordering a service that has been deactivated returns {"error": "Service not available"}; an unknown service id returns {"error": "Service not found"}.

Parameters

Name Required Description
key yes Your API key (or send X-API-Key).
action yes add
service yes The integer service id (e.g. 200 for Views).
link yes The target URL (e.g. the tweet/post URL).
quantity yes Number of units to deliver, within the service's min/max.

Idempotency

Send an optional Idempotency-Key HTTP header (any unique string you generate per order). If you retry a request with the same key, the original order is returned instead of creating — and charging — a second order. This makes safe retries straightforward.

curl

curl -s https://engagegate.app/api/v2 \
  -H "Idempotency-Key: my-unique-order-001" \
  -d key=YOUR_API_KEY \
  -d action=add \
  -d service=200 \
  -d link=https://x.com/someuser/status/1234567890 \
  -d quantity=5000

Python

import requests
import uuid

resp = requests.post(
    "https://engagegate.app/api/v2",
    headers={"Idempotency-Key": str(uuid.uuid4())},
    data={
        "key": "YOUR_API_KEY",
        "action": "add",
        "service": "200",
        "link": "https://x.com/someuser/status/1234567890",
        "quantity": "5000",
    },
)
print(resp.json())

Example response

{ "order": 10042 }

The order value is an integer order id — pass it to status and cancel.

Common add errors

Error Meaning
{"error":"Invalid service"} service was missing or not an integer.
{"error":"Service not found"} No active service with that id.
{"error":"Service not available"} That service is currently deactivated and not orderable.
{"error":"Missing link"} link was empty.
{"error":"Invalid quantity"} quantity was non-numeric or outside min/max.
{"error":"Not enough funds"} Your wallet balance is below the order charge. No charge is made.
{"error":"Fulfillment temporarily unavailable"} The order could not be placed; a refund of the charge is issued to your wallet after review.

status — check order status

Look up one order or a batch of your own orders. You can only see orders placed with your own API key.

Parameters

Name Required Description
key yes Your API key (or send X-API-Key).
action yes status
order one of A single order id.
orders one of A comma-separated list of order ids (max 100). Takes precedence over order.

curl (single)

curl -s https://engagegate.app/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=status \
  -d order=3f7c2b9e-1a4d-4f2a-9c1e-8b0d6e2a5f33

Python (single)

import requests

resp = requests.post(
    "https://engagegate.app/api/v2",
    data={
        "key": "YOUR_API_KEY",
        "action": "status",
        "order": 10042,
    },
)
print(resp.json())

Example response (single)

{
  "charge": "0.90",
  "start_count": "0",
  "status": "Completed",
  "remains": "0",
  "currency": "USD"
}

Batch — pass orders (comma-separated). The response is keyed by order id; a bad id in the batch yields a per-id error and does not fail the rest:

curl -s https://engagegate.app/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=status \
  -d "orders=id-1,id-2"
{
  "id-1": {
    "charge": "0.90",
    "start_count": "0",
    "status": "Completed",
    "remains": "0",
    "currency": "USD"
  },
  "id-2": { "error": "Order not found" }
}

See Order status taxonomy for the response fields and status values.


cancel — cancel pending order(s)

Cancels one or more of your own orders that are still Pending. If the order was already charged, the order is cancelled and a refund of the charge is issued to your wallet after review. Orders that have moved past Pending cannot be cancelled.

Parameters

Name Required Description
key yes Your API key (or send X-API-Key).
action yes cancel
orders yes A comma-separated list of order ids (max 100).

curl

curl -s https://engagegate.app/api/v2 \
  -d key=YOUR_API_KEY \
  -d action=cancel \
  -d "orders=id-1,id-2"

Python

import requests

resp = requests.post(
    "https://engagegate.app/api/v2",
    data={
        "key": "YOUR_API_KEY",
        "action": "cancel",
        "orders": "id-1,id-2",
    },
)
print(resp.json())

Example response (a list of per-id results)

[
  { "order": 10042, "cancel": 1 },
  { "order": 10043, "error": "Order cannot be cancelled" }
]
  • {"order": id, "cancel": 1} — cancelled successfully (a refund of any charge is issued to your wallet after review).
  • {"order": id, "error": "Order cannot be cancelled"} — the order is no longer Pending (already processing or terminal).
  • {"order": id, "error": "Order not found"} — unknown id, or not one of your orders.

A request-level problem (no ids, or more than 100) returns the top-level error envelope, e.g. {"error": "No orders specified"} or {"error": "Too many orders"}.


refill — not supported

Refill is not supported and will not be added. Both refill and refill_status actions always return:

{ "error": "Refill not supported" }

Every catalog entry accordingly reports "refill": false.


4. Service catalog

The catalog is returned by the services action. The 7 services are below. Prices are USD.

ID Name Type Min Max Price Orderable today?
100 Likes — Standard Default 10 1,000 $10.00 / 1,000 Yes (live)
102 Retweets — Standard Default 10 1,000 $20.00 / 1,000 Yes (live)
104 Bookmarks — Standard Default 10 1,000 $6.00 / 1,000 Yes (live)
200 Views Default 100 1,000,000 Dynamic / 1,000 Yes (live)
300 Subscription Starter Package 1 1 Flat (monthly) Yes (live)
301 Subscription Growth Package 1 1 Flat (monthly) Yes (live)
302 Subscription Scale Package 1 1 Flat (monthly) Yes (live)

What's orderable today

All catalog services are live and accepted by the add action:

  • Views (200) — up to 1,000,000 per order.
  • Engagement — Likes (100), Retweets (102), Bookmarks (104) — 10–1,000 units per order.
  • Subscription packages — Starter (300), Growth (301), Scale (302) — placed with target_account + billing_period instead of link + quantity.

Placing an add for a service id that does not exist returns {"error": "Service not found"}.

Pricing notes

  • For per-1,000 services (Likes, Retweets, Bookmarks, Views), the catalog reports rate (price per 1,000) and the order charge scales linearly with quantity.
  • Views pricing is dynamic — the rate for service 200 is computed at request time and can change. Always read the current rate from services before placing a Views order rather than hard-coding a value. (The figure in the services example above is illustrative only.)
  • For Subscription packages, the catalog reports a single flat_price (the monthly price), and min/max are both 1. The current price for each package is always the flat_price returned by the services action.

5. Order status taxonomy

The status field in a status response is one of:

Status Meaning
Pending Accepted and queued; not yet started. Cancellable.
Processing Being set up for delivery.
In progress Actively delivering.
Completed Delivered in full.
Partial Delivered in part; the undelivered portion is reflected in remains.
Canceled Cancelled or terminated; any charge is refunded to your wallet after review.

A single status lookup returns this envelope:

Field Type Description
charge string The amount charged for the order (USD).
start_count string The metric count at the moment delivery began (0 until known).
status string One of the values above.
remains string Units still to be delivered (quantity − delivered).
currency string Always "USD".
{
  "charge": "0.90",
  "start_count": "0",
  "status": "In progress",
  "remains": "1200",
  "currency": "USD"
}

6. Rate limits

  • The default limit is 60 requests per minute, per API key.
  • The public services action is not rate-limited.
  • Every authenticated response includes these headers:
    • X-RateLimit-Limit — your per-minute limit.
    • X-RateLimit-Remaining — requests left in the current minute window.
  • When you exceed the limit, the response (still HTTP 200) is:
{ "error": "Rate limit exceeded" }

Back off and retry in the next minute window. Use the Idempotency-Key header on add so retries after a rate-limit hit cannot double-charge you.


7. FAQ

What is a Partial order? A Partial order is one where only some of the requested quantity could be delivered. The remains field tells you how many units were not delivered. When delivery falls short, a refund for the undelivered portion is issued to your wallet after review.

When can I cancel an order? Only while it is Pending. Once an order moves to Processing (or later), it can no longer be cancelled, and cancel returns {"order": id, "error": "Order cannot be cancelled"}. Cancelling a Pending order that was already charged issues a refund to your wallet after review.

How do I test my integration? Mint a sandbox API key on engagegate.app/account/api. With a sandbox key, read actions (balance, status, services) behave normally, and add returns a mock order that is immediately Completedno wallet charge and no real engagement. This lets you exercise the full request/response flow safely.

Is my balance refunded if an order fails? Yes. If you have funds but fulfillment fails after the charge, the order is marked failed and a refund of the charge is issued to your wallet after review, and add returns {"error": "Fulfillment temporarily unavailable"}. Refunds are reviewed before the credit is applied, so your balance updates once that review completes. If you simply lack the funds, no charge is made at all and you get {"error": "Not enough funds"}.

What happens if fulfillment fails? EngageGate marks the order failed and a refund of the charge is issued to your wallet after review. You can safely retry (use an Idempotency-Key to make retries safe).

Why do all responses return HTTP 200? That is the SMM-panel V2 convention this API follows. Detect failures by checking for an error key in the JSON body, not by the HTTP status code.

Can I send JSON instead of form data? Yes — set Content-Type: application/json and send the same fields as a JSON object. Form-encoded (application/x-www-form-urlencoded) is recommended and is the protocol default.