{
  "openapi": "3.0.3",
  "info": {
    "title": "SMM Africa Growth API",
    "description": "Single-endpoint, action-based JSON API for placing, tracking, refilling, and cancelling social growth orders. Direct orders, storefront orders, and API orders all draw from the same wallet balance.",
    "version": "3.0.0",
    "contact": {
      "name": "SMM Africa support",
      "url": "https://smm.africa/contact-us"
    },
    "license": {
      "name": "Commercial",
      "url": "https://smm.africa/terms"
    }
  },
  "servers": [
    { "url": "https://smm.africa/api/v3", "description": "Production" }
  ],
  "tags": [
    { "name": "Account", "description": "Wallet balance and key checks" },
    { "name": "Catalog", "description": "Live service catalog" },
    { "name": "Orders", "description": "Place, track, refill, and cancel orders" }
  ],
  "paths": {
    "/": {
      "post": {
        "summary": "Execute an action",
        "description": "All operations use the same POST endpoint. The `action` field in the JSON body decides which operation runs. Every request requires the `key` field, which is issued per account.",
        "operationId": "executeAction",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { "$ref": "#/components/schemas/BalanceRequest" },
                  { "$ref": "#/components/schemas/ServicesRequest" },
                  { "$ref": "#/components/schemas/AddRequest" },
                  { "$ref": "#/components/schemas/StatusRequest" },
                  { "$ref": "#/components/schemas/RefillRequest" },
                  { "$ref": "#/components/schemas/CancelRequest" }
                ]
              },
              "examples": {
                "balance": {
                  "summary": "Wallet balance check",
                  "value": { "key": "YOUR_API_KEY", "action": "balance" }
                },
                "services": {
                  "summary": "Full service catalog",
                  "value": { "key": "YOUR_API_KEY", "action": "services" }
                },
                "add": {
                  "summary": "Place a new order",
                  "value": {
                    "key": "YOUR_API_KEY",
                    "action": "add",
                    "service": 1234,
                    "link": "https://instagram.com/your-profile",
                    "quantity": 500
                  }
                },
                "status": {
                  "summary": "Check a single order",
                  "value": { "key": "YOUR_API_KEY", "action": "status", "order": "987654" }
                },
                "refill": {
                  "summary": "Request a refill",
                  "value": { "key": "YOUR_API_KEY", "action": "refill", "order": "987654" }
                },
                "cancel": {
                  "summary": "Request cancellation",
                  "value": { "key": "YOUR_API_KEY", "action": "cancel", "order": "987654" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action executed successfully. Response shape depends on action.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    { "$ref": "#/components/schemas/BalanceResponse" },
                    { "$ref": "#/components/schemas/ServicesResponse" },
                    { "$ref": "#/components/schemas/AddResponse" },
                    { "$ref": "#/components/schemas/StatusResponse" },
                    { "$ref": "#/components/schemas/ActionAcknowledgement" }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or missing required field.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
          },
          "429": {
            "description": "Rate limited. Back off and retry after the window resets.",
            "headers": {
              "Retry-After": {
                "schema": { "type": "integer" },
                "description": "Seconds to wait before retrying."
              }
            },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
          },
          "500": {
            "description": "Upstream or server error.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "BalanceRequest": {
        "type": "object",
        "required": ["key", "action"],
        "properties": {
          "key": { "type": "string", "description": "Account API key." },
          "action": { "type": "string", "enum": ["balance"] }
        }
      },
      "ServicesRequest": {
        "type": "object",
        "required": ["key", "action"],
        "properties": {
          "key": { "type": "string" },
          "action": { "type": "string", "enum": ["services"] }
        }
      },
      "AddRequest": {
        "type": "object",
        "required": ["key", "action", "service", "link", "quantity"],
        "properties": {
          "key": { "type": "string" },
          "action": { "type": "string", "enum": ["add"] },
          "service": { "type": "integer", "description": "Service ID from the services action." },
          "link": { "type": "string", "description": "Target URL or username, as accepted by the service." },
          "quantity": { "type": "integer", "description": "Must be between the service's min and max." },
          "runs": { "type": "integer", "description": "Drip-feed runs (optional, service-dependent)." },
          "interval": { "type": "integer", "description": "Drip-feed interval in minutes (optional)." }
        }
      },
      "StatusRequest": {
        "type": "object",
        "required": ["key", "action", "order"],
        "properties": {
          "key": { "type": "string" },
          "action": { "type": "string", "enum": ["status"] },
          "order": { "type": "string", "description": "Order ID returned from the add action." }
        }
      },
      "RefillRequest": {
        "type": "object",
        "required": ["key", "action", "order"],
        "properties": {
          "key": { "type": "string" },
          "action": { "type": "string", "enum": ["refill"] },
          "order": { "type": "string" }
        }
      },
      "CancelRequest": {
        "type": "object",
        "required": ["key", "action", "order"],
        "properties": {
          "key": { "type": "string" },
          "action": { "type": "string", "enum": ["cancel"] },
          "order": { "type": "string" }
        }
      },
      "BalanceResponse": {
        "type": "object",
        "properties": {
          "balance": { "type": "string", "example": "123.4500" },
          "currency": { "type": "string", "example": "USD" }
        }
      },
      "ServicesResponse": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "service": { "type": "integer", "example": 1234 },
            "name": { "type": "string", "example": "Instagram Followers | High Quality | 10K/Day" },
            "type": { "type": "string", "example": "Default" },
            "category": { "type": "string", "example": "Instagram Followers" },
            "rate": { "type": "string", "description": "Price per 1000 in your wallet currency." },
            "min": { "type": "integer" },
            "max": { "type": "integer" },
            "refill": { "type": "boolean" },
            "cancel": { "type": "boolean" }
          }
        }
      },
      "AddResponse": {
        "type": "object",
        "properties": {
          "order": { "type": "string", "description": "Store this ID and reuse it for status, refill, and cancel." }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "charge": { "type": "string" },
          "start_count": { "type": "string" },
          "status": {
            "type": "string",
            "enum": ["Pending", "In progress", "Processing", "Partial", "Completed", "Canceled"]
          },
          "remains": { "type": "string" },
          "currency": { "type": "string" }
        }
      },
      "ActionAcknowledgement": {
        "type": "object",
        "properties": {
          "order": { "type": "string" },
          "refill": { "type": "string", "description": "Returned for refill action." },
          "cancel": { "type": "string", "description": "Returned for cancel action." }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": { "type": "string" }
        }
      }
    }
  }
}
