{
  "openapi": "3.0.3",
  "info": {
    "title": "SMMSCORE Native API",
    "version": "1.2.0",
    "description": "JSON backend for native clients. Providers = catalog platforms. All wallet and order amounts use coins: $1 = 100 coins. Bearer tokens expire after 30 days. Errors have stable English codes/messages; catalog language uses ?language= or Accept-Language. Pagination defaults to 20 and caps at 100. Rate limits return HTTP 429 and Retry-After. API has no cookie/session requirement."
  },
  "servers": [
    {
      "url": "/api/v1",
      "description": "Current host"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Authentication"
    },
    {
      "name": "Account"
    },
    {
      "name": "Catalog"
    },
    {
      "name": "Wallet"
    },
    {
      "name": "Orders"
    },
    {
      "name": "Google Play"
    },
    {
      "name": "Legal"
    }
  ],
  "paths": {
    "/auth/register": {
      "post": {
        "operationId": "register",
        "tags": [
          "Authentication"
        ],
        "summary": "Create an account and issue a 30-day token",
        "description": "Existing active, banned or deleted emails cannot be registered again. Verification email is best effort. The account can be used immediately.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Registration"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 254
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "description": "8–72 UTF-8 bytes; never truncated."
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "de",
                      "fr",
                      "es",
                      "pt",
                      "ru",
                      "tr",
                      "ar",
                      "zh",
                      "ja",
                      "ko",
                      "hi",
                      "id",
                      "vi",
                      "th",
                      "bn",
                      "bg",
                      "hu",
                      "el",
                      "ka",
                      "da",
                      "he",
                      "is",
                      "it",
                      "lv",
                      "lt",
                      "nl",
                      "nb",
                      "fa",
                      "pl",
                      "ro",
                      "sk",
                      "sl",
                      "uk",
                      "ur",
                      "fil",
                      "fi",
                      "hr",
                      "cs",
                      "sv",
                      "et"
                    ]
                  }
                },
                "required": [
                  "email",
                  "password"
                ]
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "operationId": "login",
        "tags": [
          "Authentication"
        ],
        "summary": "Sign in with an existing account",
        "description": "Existing website accounts use the same password. Deleted and banned users cannot sign in. No cookies or CSRF token are required.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Auth"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "password": {
                    "type": "string",
                    "format": "password"
                  }
                },
                "required": [
                  "email",
                  "password"
                ]
              }
            }
          }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "operationId": "logout",
        "tags": [
          "Authentication"
        ],
        "summary": "Revoke this access token",
        "description": "No request body required. Other devices retain their tokens.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "logged_out": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "logged_out"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/me": {
      "get": {
        "operationId": "currentUser",
        "tags": [
          "Account"
        ],
        "summary": "Get the current account",
        "description": "",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/User"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      },
      "patch": {
        "operationId": "updateProfile",
        "tags": [
          "Account"
        ],
        "summary": "Update account details",
        "description": "Provide at least one of name, phone or language. Email and wallet balance cannot be edited here.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/User"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "phone": {
                    "type": "string",
                    "maxLength": 32
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "de",
                      "fr",
                      "es",
                      "pt",
                      "ru",
                      "tr",
                      "ar",
                      "zh",
                      "ja",
                      "ko",
                      "hi",
                      "id",
                      "vi",
                      "th",
                      "bn",
                      "bg",
                      "hu",
                      "el",
                      "ka",
                      "da",
                      "he",
                      "is",
                      "it",
                      "lv",
                      "lt",
                      "nl",
                      "nb",
                      "fa",
                      "pl",
                      "ro",
                      "sk",
                      "sl",
                      "uk",
                      "ur",
                      "fil",
                      "fi",
                      "hr",
                      "cs",
                      "sv",
                      "et"
                    ]
                  }
                },
                "required": []
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAccount",
        "tags": [
          "Account"
        ],
        "summary": "Delete your account",
        "description": "Soft deletion immediately disables access on all devices. Financial records remain for accounting. This action is irreversible through the API. Confirm with the SMMSCORE password or, for a linked Google account, a fresh Google ID token obtained with /auth/google/challenge and Credential Manager. The Google sub must match this user.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "account_deleted": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "account_deleted"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password"
                  },
                  "confirm": {
                    "type": "boolean",
                    "enum": [
                      true
                    ]
                  },
                  "id_token": {
                    "type": "string",
                    "maxLength": 16384,
                    "description": "Fresh Google proof for the linked identity; must contain an unused server nonce."
                  }
                },
                "required": [
                  "confirm"
                ],
                "anyOf": [
                  {
                    "required": [
                      "password"
                    ]
                  },
                  {
                    "required": [
                      "id_token"
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/me/password": {
      "post": {
        "operationId": "changePassword",
        "tags": [
          "Account"
        ],
        "summary": "Change password and revoke all access tokens",
        "description": "After success, log in again with the new password.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "password_changed": {
                          "type": "boolean"
                        },
                        "login_required": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "password_changed",
                        "login_required"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "current_password": {
                    "type": "string",
                    "format": "password"
                  },
                  "new_password": {
                    "type": "string",
                    "format": "password",
                    "description": "8–72 UTF-8 bytes."
                  }
                },
                "required": [
                  "current_password",
                  "new_password"
                ]
              }
            }
          }
        }
      }
    },
    "/languages": {
      "get": {
        "operationId": "languages",
        "tags": [
          "Catalog"
        ],
        "summary": "List all supported languages",
        "description": "",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Language"
                          }
                        }
                      },
                      "required": [
                        "items"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "security": []
      }
    },
    "/providers": {
      "get": {
        "operationId": "providers",
        "tags": [
          "Catalog"
        ],
        "summary": "List catalog platforms",
        "description": "Providers here are Telegram, Instagram, TikTok, etc. Internal supplier details and credentials are never exposed. Hidden platforms are excluded; Russia-only platforms are available only for language=ru.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Provider"
                          }
                        },
                        "language": {
                          "type": "string",
                          "enum": [
                            "en",
                            "de",
                            "fr",
                            "es",
                            "pt",
                            "ru",
                            "tr",
                            "ar",
                            "zh",
                            "ja",
                            "ko",
                            "hi",
                            "id",
                            "vi",
                            "th",
                            "bn",
                            "bg",
                            "hu",
                            "el",
                            "ka",
                            "da",
                            "he",
                            "is",
                            "it",
                            "lv",
                            "lt",
                            "nl",
                            "nb",
                            "fa",
                            "pl",
                            "ro",
                            "sk",
                            "sl",
                            "uk",
                            "ur",
                            "fil",
                            "fi",
                            "hr",
                            "cs",
                            "sv",
                            "et"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "language"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "security": []
      }
    },
    "/service-types": {
      "get": {
        "operationId": "serviceTypes",
        "tags": [
          "Catalog"
        ],
        "summary": "List visible service types",
        "description": "",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "provider_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "Catalog platform ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ServiceType"
                          }
                        },
                        "language": {
                          "type": "string",
                          "enum": [
                            "en",
                            "de",
                            "fr",
                            "es",
                            "pt",
                            "ru",
                            "tr",
                            "ar",
                            "zh",
                            "ja",
                            "ko",
                            "hi",
                            "id",
                            "vi",
                            "th",
                            "bn",
                            "bg",
                            "hu",
                            "el",
                            "ka",
                            "da",
                            "he",
                            "is",
                            "it",
                            "lv",
                            "lt",
                            "nl",
                            "nb",
                            "fa",
                            "pl",
                            "ro",
                            "sk",
                            "sl",
                            "uk",
                            "ur",
                            "fil",
                            "fi",
                            "hr",
                            "cs",
                            "sv",
                            "et"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "language"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "security": []
      }
    },
    "/services": {
      "get": {
        "operationId": "services",
        "tags": [
          "Catalog"
        ],
        "summary": "List visible services",
        "description": "",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "provider_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "Catalog platform ID."
          },
          {
            "name": "type_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "Service type ID."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            },
            "description": "Page number."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Page size."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/ServiceList"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "security": []
      }
    },
    "/services/{id}": {
      "get": {
        "operationId": "serviceDetails",
        "tags": [
          "Catalog"
        ],
        "summary": "Get a visible service and description",
        "description": "",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 2147483647
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/ServiceDetail"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "security": []
      }
    },
    "/balance": {
      "get": {
        "operationId": "balance",
        "tags": [
          "Wallet"
        ],
        "summary": "Get the current coin balance",
        "description": "1 USD = 100 coins. The API does not expose the legacy USD wallet. Balance can be negative after a refunded purchase whose coins were already spent.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Balance"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/balance/history": {
      "get": {
        "operationId": "topupHistory",
        "tags": [
          "Wallet"
        ],
        "summary": "List wallet top-ups and refunds",
        "description": "Paginated, newest first. A refund preserves the original top-up and adds a negative event. This is not an order/task spending ledger.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            },
            "description": "Page number."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Page size."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/PaymentList"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/orders/quote": {
      "post": {
        "operationId": "quoteOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Validate an order and calculate its coin total",
        "description": "Does not create, dispatch or charge an order. A final total is rounded to an integer coin and must be at least one coin. Services may change between quote and creation; creation recalculates the price.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Quote"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderInput"
              }
            }
          }
        }
      }
    },
    "/orders": {
      "post": {
        "operationId": "createOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Create an order and reserve its coin total",
        "description": "An atomic wallet debit and durable order record precede supplier dispatch. A repeated key with the same payload returns the existing order (200) without another charge; a different payload returns 409. Supplier failures or ambiguous responses produce needs_review and keep coins reserved for manual reconciliation. Never create a new key just because the request timed out.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$",
              "example": "order-550e8400-e29b-41d4-a716-446655440000"
            },
            "description": "Unique per new order; persist and reuse the SAME key and payload after timeout or network failure."
          }
        ],
        "responses": {
          "200": {
            "description": "Idempotent replay; no second debit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/OrderCreated"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/OrderCreated"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderInput"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "myOrders",
        "tags": [
          "Orders"
        ],
        "summary": "List my orders",
        "description": "Includes old confirmed orders and API reservations. Never exposes another user's orders.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            },
            "description": "Page number."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Page size."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/OrderList"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/orders/{id}": {
      "get": {
        "operationId": "orderDetails",
        "tags": [
          "Orders"
        ],
        "summary": "Get my order status",
        "description": "",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 2147483647
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Order"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/billing/google/config": {
      "get": {
        "operationId": "googleConfig",
        "tags": [
          "Google Play"
        ],
        "summary": "Get products and billing account binding",
        "description": "Google Play prices and eligible offers come from Android BillingClient ProductDetails. credit_coins is the base wallet credit. repeat_bonus describes the account-specific one-time 10% bonus.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/GoogleConfig"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/billing/google/prepare": {
      "post": {
        "operationId": "googlePrepare",
        "tags": [
          "Google Play"
        ],
        "summary": "Prepare a coin top-up",
        "description": "Create an intent before launchBillingFlow. Pass obfuscated_account_id to setObfuscatedAccountId and obfuscated_profile_id to setObfuscatedProfileId. Existing product IDs stay unchanged.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/GooglePrepared"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "product_id": {
                    "type": "string",
                    "example": "smmscore_balance_2"
                  }
                },
                "required": [
                  "product_id"
                ]
              }
            }
          }
        }
      }
    },
    "/billing/google/verify": {
      "post": {
        "operationId": "googleVerify",
        "tags": [
          "Google Play"
        ],
        "summary": "Verify a purchase token and credit coins once",
        "description": "Send the Play purchase token from onPurchasesUpdated or recovered purchases. The server verifies ownership and product with Google, credits the wallet once and consumes the purchase. Test purchases follow the same accounting. Pending purchases are not credited. Google worker retries consumption and handles refunds.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/GoogleVerified"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "purchase_token": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 4096
                  }
                },
                "required": [
                  "purchase_token"
                ]
              }
            }
          }
        }
      }
    },
    "/billing/google/status": {
      "get": {
        "operationId": "googleStatus",
        "tags": [
          "Google Play"
        ],
        "summary": "Poll a top-up intent",
        "description": "Read-only reconciliation. Poll while waiting; fetch /balance after credit.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Catalog language. Overrides Accept-Language; fallback en. Saved account preference is returned in /me and can be sent by the client."
          },
          {
            "name": "intent_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{32}$"
            },
            "description": "Your own intent ID from prepare."
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/GoogleStatus"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/auth/google/challenge": {
      "post": {
        "operationId": "googleChallenge",
        "tags": [
          "Authentication"
        ],
        "security": [],
        "summary": "Start Google sign-in",
        "description": "Send {} before each Google account picker. Use server_client_id as Credential Manager serverClientId and nonce as setNonce. Nonce is single-use and expires in 5 minutes. Public client ID is not an application secret. Returns 503 google_auth_not_configured until the Web OAuth client ID is configured.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "example": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "nonce": {
                          "type": "string",
                          "pattern": "^[a-f0-9]{64}$"
                        },
                        "server_client_id": {
                          "type": "string",
                          "example": "123-example.apps.googleusercontent.com"
                        },
                        "expires_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "nonce",
                        "server_client_id",
                        "expires_at"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/auth/google": {
      "post": {
        "operationId": "googleLogin",
        "tags": [
          "Authentication"
        ],
        "security": [],
        "summary": "Exchange a Google ID token for an API session",
        "description": "Requires a Google RS256 ID token with the issued nonce, matching Web client audience and verified email. A new identity creates a user with zero coins. Known identities are resolved by Google sub. Existing email accounts return 409 google_link_required; retry the same proof with existing_password to link without losing balance/history. Wrong linking password returns 401 incorrect_link_password. Another linked identity returns 409 google_account_already_linked. Successful exchange consumes the nonce. Expired/replayed nonce returns 401 google_challenge_expired. Banned/deleted users cannot sign in.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id_token": {
                    "type": "string",
                    "maxLength": 16384,
                    "description": "Google ID token; never log or persist it."
                  },
                  "existing_password": {
                    "type": "string",
                    "format": "password",
                    "description": "Existing SMMSCORE password, only for explicit account linking. Maximum 72 UTF-8 bytes."
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "de",
                      "fr",
                      "es",
                      "pt",
                      "ru",
                      "tr",
                      "ar",
                      "zh",
                      "ja",
                      "ko",
                      "hi",
                      "id",
                      "vi",
                      "th",
                      "bn",
                      "bg",
                      "hu",
                      "el",
                      "ka",
                      "da",
                      "he",
                      "is",
                      "it",
                      "lv",
                      "lt",
                      "nl",
                      "nb",
                      "fa",
                      "pl",
                      "ro",
                      "sk",
                      "sl",
                      "uk",
                      "ur",
                      "fil",
                      "fi",
                      "hr",
                      "cs",
                      "sv",
                      "et"
                    ]
                  }
                },
                "required": [
                  "id_token"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/GoogleAuth"
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/legal/privacy": {
      "get": {
        "operationId": "privacyPolicy",
        "tags": [
          "Legal"
        ],
        "security": [],
        "summary": "Read the privacy policy as native text",
        "description": "Public; no account or Bearer token required. Render blocks as native text, without a WebView. The Content-Language header reflects content_language. Source policy wording is preserved, including textual legal/contact addresses.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Document language. Overrides Accept-Language; fallback en. Missing document translations also fall back to en; inspect content_language."
          }
        ],
        "responses": {
          "200": {
            "description": "Versioned document",
            "headers": {
              "Content-Language": {
                "schema": {
                  "type": "string"
                },
                "description": "Actual document language."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/LegalDocument"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    },
    "/legal/terms": {
      "get": {
        "operationId": "termsOfService",
        "tags": [
          "Legal"
        ],
        "security": [],
        "summary": "Read the terms of service as native text",
        "description": "Public; no account or Bearer token required. Render blocks as native text, without a WebView. The Content-Language header reflects content_language. Source policy wording is preserved, including textual legal/contact addresses.",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de",
                "fr",
                "es",
                "pt",
                "ru",
                "tr",
                "ar",
                "zh",
                "ja",
                "ko",
                "hi",
                "id",
                "vi",
                "th",
                "bn",
                "bg",
                "hu",
                "el",
                "ka",
                "da",
                "he",
                "is",
                "it",
                "lv",
                "lt",
                "nl",
                "nb",
                "fa",
                "pl",
                "ro",
                "sk",
                "sl",
                "uk",
                "ur",
                "fil",
                "fi",
                "hr",
                "cs",
                "sv",
                "et"
              ]
            },
            "description": "Document language. Overrides Accept-Language; fallback en. Missing document translations also fall back to en; inspect content_language."
          }
        ],
        "responses": {
          "200": {
            "description": "Versioned document",
            "headers": {
              "Content-Language": {
                "schema": {
                  "type": "string"
                },
                "description": "Actual document language."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/LegalDocument"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Paste access_token from registration/login (without the Bearer prefix)."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": true
              }
            },
            "required": [
              "code",
              "message",
              "details"
            ]
          }
        },
        "required": [
          "success",
          "error"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "language": {
            "type": "string",
            "enum": [
              "en",
              "de",
              "fr",
              "es",
              "pt",
              "ru",
              "tr",
              "ar",
              "zh",
              "ja",
              "ko",
              "hi",
              "id",
              "vi",
              "th",
              "bn",
              "bg",
              "hu",
              "el",
              "ka",
              "da",
              "he",
              "is",
              "it",
              "lv",
              "lt",
              "nl",
              "nb",
              "fa",
              "pl",
              "ro",
              "sk",
              "sl",
              "uk",
              "ur",
              "fil",
              "fi",
              "hr",
              "cs",
              "sv",
              "et"
            ]
          },
          "email_confirmed": {
            "type": "boolean"
          },
          "balance_coins": {
            "type": "integer",
            "format": "int64",
            "example": 200
          },
          "registered_at": {
            "type": "string",
            "format": "date-time"
          },
          "google_linked": {
            "type": "boolean",
            "description": "Whether Google sign-in is linked to this account."
          }
        },
        "required": [
          "id",
          "email",
          "name",
          "phone",
          "language",
          "email_confirmed",
          "balance_coins",
          "registered_at",
          "google_linked"
        ]
      },
      "Auth": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "Bearer"
            ]
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "user": {
            "$ref": "#/components/schemas/User"
          }
        },
        "required": [
          "access_token",
          "token_type",
          "expires_at",
          "user"
        ]
      },
      "Registration": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Auth"
          },
          {
            "type": "object",
            "properties": {
              "verification_email_sent": {
                "type": "boolean"
              }
            },
            "required": [
              "verification_email_sent"
            ]
          }
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "format": "int64",
            "minimum": 1
          },
          "per_page": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "maximum": 100
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "total_pages": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          }
        },
        "required": [
          "page",
          "per_page",
          "total",
          "total_pages"
        ]
      },
      "Language": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "en",
              "de",
              "fr",
              "es",
              "pt",
              "ru",
              "tr",
              "ar",
              "zh",
              "ja",
              "ko",
              "hi",
              "id",
              "vi",
              "th",
              "bn",
              "bg",
              "hu",
              "el",
              "ka",
              "da",
              "he",
              "is",
              "it",
              "lv",
              "lt",
              "nl",
              "nb",
              "fa",
              "pl",
              "ro",
              "sk",
              "sl",
              "uk",
              "ur",
              "fil",
              "fi",
              "hr",
              "cs",
              "sv",
              "et"
            ]
          },
          "name": {
            "type": "string",
            "example": "English"
          },
          "rtl": {
            "type": "boolean"
          }
        },
        "required": [
          "code",
          "name",
          "rtl"
        ]
      },
      "Provider": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "example": "Telegram"
          },
          "slug": {
            "type": "string",
            "example": "telegram"
          },
          "icon_url": {
            "type": "string",
            "nullable": true,
            "description": "Icon URL/path, resolved against the API origin."
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "slug",
          "icon_url",
          "description"
        ]
      },
      "ServiceType": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "provider_id": {
            "type": "integer",
            "format": "int64",
            "description": "Catalog platform ID."
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "icon_url": {
            "type": "string",
            "nullable": true
          },
          "link_placeholder": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "provider_id",
          "name",
          "slug",
          "icon_url",
          "link_placeholder",
          "description"
        ]
      },
      "Service": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "provider_id": {
            "type": "integer",
            "format": "int64",
            "description": "Catalog platform ID, never a supplier ID."
          },
          "type_id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "price_per_1000_coins": {
            "type": "number",
            "example": 1600,
            "description": "Coin rate per 1000 units. Rates can be fractional; quote rounds only the final order total."
          },
          "min_quantity": {
            "type": "integer",
            "format": "int64"
          },
          "max_quantity": {
            "type": "integer",
            "format": "int64"
          },
          "default_quantity": {
            "type": "integer",
            "format": "int64"
          },
          "quality": {
            "type": "integer",
            "format": "int64"
          },
          "speed": {
            "type": "integer",
            "format": "int64"
          }
        },
        "required": [
          "id",
          "provider_id",
          "type_id",
          "name",
          "description",
          "price_per_1000_coins",
          "min_quantity",
          "max_quantity",
          "default_quantity",
          "quality",
          "speed"
        ]
      },
      "ServiceDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Service"
          },
          {
            "type": "object",
            "properties": {
              "description_html": {
                "type": "string",
                "description": "Catalog editorial HTML. Sanitize before rendering. Embedded text may contain legacy currency references; numeric price fields are authoritative."
              },
              "link_validation_hint": {
                "type": "string"
              }
            },
            "required": [
              "description_html",
              "link_validation_hint"
            ]
          }
        ]
      },
      "OrderInput": {
        "type": "object",
        "properties": {
          "service_id": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "example": 123
          },
          "quantity": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "example": 100
          },
          "link": {
            "type": "string",
            "maxLength": 2048,
            "example": "https://t.me/example_channel"
          }
        },
        "required": [
          "service_id",
          "quantity",
          "link"
        ]
      },
      "Quote": {
        "type": "object",
        "properties": {
          "service_id": {
            "type": "integer",
            "format": "int64"
          },
          "quantity": {
            "type": "integer",
            "format": "int64"
          },
          "link": {
            "type": "string"
          },
          "total_coins": {
            "type": "integer",
            "format": "int64",
            "example": 160
          }
        },
        "required": [
          "service_id",
          "quantity",
          "link",
          "total_coins"
        ]
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "service_id": {
            "type": "integer",
            "format": "int64"
          },
          "service_name": {
            "type": "string"
          },
          "provider_id": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "link": {
            "type": "string"
          },
          "quantity": {
            "type": "integer",
            "format": "int64"
          },
          "total_coins": {
            "type": "integer",
            "format": "int64",
            "example": 160
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "pending",
              "in_progress",
              "partial",
              "cancelled",
              "completed",
              "needs_review"
            ]
          },
          "remains": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "service_id",
          "service_name",
          "provider_id",
          "link",
          "quantity",
          "total_coins",
          "status",
          "remains",
          "created_at",
          "finished_at"
        ]
      },
      "OrderCreated": {
        "type": "object",
        "properties": {
          "order": {
            "$ref": "#/components/schemas/Order"
          },
          "replayed": {
            "type": "boolean"
          },
          "balance_coins": {
            "type": "integer",
            "format": "int64",
            "example": 40
          }
        },
        "required": [
          "order",
          "replayed",
          "balance_coins"
        ]
      },
      "Balance": {
        "type": "object",
        "properties": {
          "balance_coins": {
            "type": "integer",
            "format": "int64",
            "example": 200
          },
          "unit": {
            "type": "string",
            "enum": [
              "coin"
            ]
          }
        },
        "required": [
          "balance_coins",
          "unit"
        ]
      },
      "Payment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "amount_coins": {
            "type": "integer",
            "format": "int64",
            "example": 200,
            "description": "Positive amount, including any repeat bonus."
          },
          "payment_provider_id": {
            "type": "integer",
            "format": "int64",
            "description": "Payment processor ID; 90 = Google Play."
          },
          "paid_at": {
            "type": "string",
            "format": "date-time",
            "description": "Event time: original credit time or refund time."
          },
          "operation_id": {
            "type": "string",
            "example": "top_up:123",
            "description": "Unique event ID; the original credit and its refund share payment id, not operation_id."
          },
          "type": {
            "type": "string",
            "enum": [
              "top_up",
              "refund"
            ]
          },
          "delta_coins": {
            "type": "integer",
            "format": "int64",
            "description": "Signed wallet change; negative for a refund.",
            "example": -550
          },
          "bonus_coins": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Bonus already included in amount_coins, not an additional credit.",
            "example": 50
          },
          "google_order_id": {
            "type": "string",
            "nullable": true,
            "description": "Google Play order reference, when available."
          }
        },
        "required": [
          "id",
          "amount_coins",
          "payment_provider_id",
          "paid_at",
          "operation_id",
          "type",
          "delta_coins",
          "bonus_coins",
          "google_order_id"
        ],
        "description": "A wallet top-up or Google Play refund. Both events remain visible after a refund."
      },
      "GoogleProduct": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "string",
            "example": "smmscore_balance_2"
          },
          "credit_coins": {
            "type": "integer",
            "format": "int64",
            "example": 200
          }
        },
        "required": [
          "product_id",
          "credit_coins"
        ]
      },
      "GoogleConfig": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GoogleProduct"
            }
          },
          "obfuscated_account_id": {
            "type": "string"
          },
          "repeat_bonus": {
            "$ref": "#/components/schemas/RepeatBonus"
          }
        },
        "required": [
          "enabled",
          "products",
          "obfuscated_account_id",
          "repeat_bonus"
        ]
      },
      "GooglePrepared": {
        "type": "object",
        "properties": {
          "intent_id": {
            "type": "string",
            "pattern": "^[a-f0-9]{32}$"
          },
          "product_id": {
            "type": "string"
          },
          "obfuscated_account_id": {
            "type": "string"
          },
          "obfuscated_profile_id": {
            "type": "string",
            "description": "Pass to BillingFlowParams.setObfuscatedProfileId."
          }
        },
        "required": [
          "intent_id",
          "product_id",
          "obfuscated_account_id",
          "obfuscated_profile_id"
        ]
      },
      "GoogleVerified": {
        "type": "object",
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "credited",
              "pending",
              "cancelled"
            ]
          },
          "balance_coins": {
            "type": "integer",
            "format": "int64"
          },
          "credited_coins": {
            "type": "integer",
            "format": "int64",
            "description": "Recorded credit, including bonus; never add this locally. Refetch /balance. Zero if not credited yet."
          },
          "payment_id": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Stable payment ID for receipt deduplication; null before credit."
          }
        },
        "required": [
          "state",
          "balance_coins",
          "credited_coins",
          "payment_id"
        ]
      },
      "GoogleStatus": {
        "type": "object",
        "properties": {
          "intent_id": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "enum": [
              "waiting",
              "credited",
              "cancelled"
            ]
          },
          "balance_coins": {
            "type": "integer",
            "format": "int64"
          },
          "credited_coins": {
            "type": "integer",
            "format": "int64",
            "description": "Recorded credit, including bonus; never add this locally. Refetch /balance. Zero if not credited yet."
          },
          "payment_id": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Stable payment ID for receipt deduplication; null before credit."
          }
        },
        "required": [
          "intent_id",
          "state",
          "balance_coins",
          "credited_coins",
          "payment_id"
        ]
      },
      "ServiceList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Service"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "items",
          "pagination"
        ]
      },
      "OrderList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Order"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "items",
          "pagination"
        ]
      },
      "PaymentList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Payment"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "items",
          "pagination"
        ]
      },
      "GoogleAuth": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Auth"
          },
          {
            "type": "object",
            "properties": {
              "created": {
                "type": "boolean",
                "description": "True only when this exchange creates a new user."
              }
            },
            "required": [
              "created"
            ]
          }
        ]
      },
      "LegalDocument": {
        "type": "object",
        "required": [
          "document",
          "language",
          "content_language",
          "title",
          "version",
          "blocks"
        ],
        "properties": {
          "document": {
            "type": "string",
            "enum": [
              "privacy",
              "terms"
            ]
          },
          "language": {
            "type": "string",
            "description": "Requested language after negotiation."
          },
          "content_language": {
            "type": "string",
            "description": "Actual text language. Missing translations fall back to en; terms currently support ru and en."
          },
          "title": {
            "type": "string"
          },
          "version": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "SHA-256 of the rendered source; changes when document text or public placeholders change."
          },
          "blocks": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type",
                "text"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "heading",
                    "paragraph",
                    "list_item"
                  ]
                },
                "text": {
                  "type": "string",
                  "description": "Plain Unicode text; may include line breaks. No HTML, executable templates, or clickable links."
                }
              }
            }
          }
        }
      },
      "RepeatBonus": {
        "type": "object",
        "required": [
          "percent",
          "status",
          "expires_at"
        ],
        "description": "One bonus on the second successful top-up within seven days of the first. Refunding a bonus purchase does not restore eligibility.",
        "properties": {
          "percent": {
            "type": "integer",
            "enum": [
              10
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "after_first",
              "eligible",
              "unavailable"
            ],
            "description": "after_first: no successful top-up yet; eligible: next top-up qualifies; unavailable: expired or already used."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Expiry while eligible; null otherwise."
          }
        }
      }
    },
    "responses": {
      "ApiError": {
        "description": "JSON error: 400 invalid JSON/purchase; 401 invalid credentials/token; 404 unavailable resource; 405 unsupported method; 409 email, idempotency or balance conflict; 413 body too large; 415 content type; 422 validation; 429 rate limited (Retry-After header); 503 temporary service/schema failure.",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait for a 429 response.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          "WWW-Authenticate": {
            "description": "Bearer for 401 responses.",
            "schema": {
              "type": "string"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "success": false,
              "error": {
                "code": "insufficient_coins",
                "message": "Not enough coins.",
                "details": {
                  "required_coins": 160
                }
              }
            }
          }
        }
      }
    }
  }
}
