{"openapi":"3.1.0","info":{"title":"VPN Site API v2","description":"API for payment-site integration with VPN configs.\n\n### Mini Doc\n\n- Base URL: `https://monetto.devasvarupa.ru`\n- Docs: `GET /swagger`, `GET /swagger/v1`, `GET /swagger/v2`\n- OpenAPI JSON: `GET /openapi/v1.json`, `GET /openapi/v2.json`\n\n### Auth\n\nAll methods require headers:\n- `X-Server-Key`\n- `X-Site-Key`\n\n- `X-Timestamp` (unix seconds)\n- `X-Signature` (hex HMAC-SHA256)\n\nSignature payload:\n```\n{timestamp}\\n{method}\\n{path}\\n{query}\\n{sha256(body)}\n```\nRules: `{path}` without host, `{query}` without `?` (exactly as sent), body hash from raw request body bytes.\nExample for empty query: keep an empty line for `{query}`.\nAllowed timestamp drift is controlled by `API_HMAC_TTL_SECONDS` (default 300).\n\nIf auth is invalid -> `HTTP 403`.\n\n### Endpoints\n\n1. `POST /api/v1/configs` - create/extend config by UID and return full config JSON\n2. `GET /api/v1/configs/{uid}` - get config JSON\n3. `POST /api/v1/configs/{uid}/pause` - pause config\n\n### curl examples\n\n```bash\ncurl -X POST 'https://monetto.devasvarupa.ru/api/v1/configs' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Server-Key: <SERVER_KEY>' \\\n  -H 'X-Site-Key: <SITE_KEY>' \\\n  -H 'X-Timestamp: <UNIX_TS>' \\\n  -H 'X-Signature: <HMAC_HEX>' \\\n  -d '{\"uid\":\"265c8f2d-7431-40e1-b5da-22630a235e6d\",\"period_days\":30,\"external_payment_id\":\"order_2026_0001\"}'\n```\n\n```bash\ncurl 'https://monetto.devasvarupa.ru/api/v1/configs/265c8f2d-7431-40e1-b5da-22630a235e6d' \\\n  -H 'X-Server-Key: <SERVER_KEY>' \\\n  -H 'X-Site-Key: <SITE_KEY>' \\\n  -H 'X-Timestamp: <UNIX_TS>' \\\n  -H 'X-Signature: <HMAC_HEX>'\n```\n\n```bash\ncurl -X POST 'https://monetto.devasvarupa.ru/api/v1/configs/265c8f2d-7431-40e1-b5da-22630a235e6d/pause' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Server-Key: <SERVER_KEY>' \\\n  -H 'X-Site-Key: <SITE_KEY>' \\\n  -H 'X-Timestamp: <UNIX_TS>' \\\n  -H 'X-Signature: <HMAC_HEX>' \\\n  -d '{\"reason\":\"payment_expired\"}'\n```","version":"1.0.0"},"paths":{"/api/v2/monetto/subscriptions":{"post":{"tags":["site-api"],"summary":"Create or extend Monetto subscription","description":"Creates or extends a Monetto subscription in the new shared infrastructure. Requires tg_username and external_payment_id.","operationId":"create_monetto_subscription_api_v2_monetto_subscriptions_post","parameters":[{"name":"X-Server-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Server API key","title":"X-Server-Key"},"description":"Server API key"},{"name":"X-Site-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Site API key","title":"X-Site-Key"},"description":"Site API key"},{"name":"X-Timestamp","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Unix timestamp (seconds)","title":"X-Timestamp"},"description":"Unix timestamp (seconds)"},{"name":"X-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"HMAC-SHA256 hex signature. Optional prefix: sha256=","title":"X-Signature"},"description":"HMAC-SHA256 hex signature. Optional prefix: sha256="}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMonettoSubscriptionRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonettoSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/monetto/subscriptions/{subscription_id}":{"get":{"tags":["site-api"],"summary":"Get Monetto subscription","description":"Returns subscription access payload for the Monetto v2 integration.","operationId":"get_monetto_subscription_api_v2_monetto_subscriptions__subscription_id__get","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","title":"Subscription Id"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"X-Server-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Server API key","title":"X-Server-Key"},"description":"Server API key"},{"name":"X-Site-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Site API key","title":"X-Site-Key"},"description":"Site API key"},{"name":"X-Timestamp","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Unix timestamp (seconds)","title":"X-Timestamp"},"description":"Unix timestamp (seconds)"},{"name":"X-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"HMAC-SHA256 hex signature. Optional prefix: sha256=","title":"X-Signature"},"description":"HMAC-SHA256 hex signature. Optional prefix: sha256="}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonettoSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/monetto/subscriptions/{subscription_id}/pause":{"post":{"tags":["site-api"],"summary":"Pause Monetto subscription","description":"Pauses the subscription without deleting local payment history.","operationId":"pause_monetto_subscription_api_v2_monetto_subscriptions__subscription_id__pause_post","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","title":"Subscription Id"}},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},{"name":"X-Server-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Server API key","title":"X-Server-Key"},"description":"Server API key"},{"name":"X-Site-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Site API key","title":"X-Site-Key"},"description":"Site API key"},{"name":"X-Timestamp","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Unix timestamp (seconds)","title":"X-Timestamp"},"description":"Unix timestamp (seconds)"},{"name":"X-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"HMAC-SHA256 hex signature. Optional prefix: sha256=","title":"X-Signature"},"description":"HMAC-SHA256 hex signature. Optional prefix: sha256="}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PauseConfigRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PauseMonettoSubscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"CreateConfigRequest":{"properties":{"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain","description":"Domain key. Optional for /api/v1/configs (will fallback to request host)."},"uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uid","description":"Config UID (UUID). If empty, generated on server."},"period_days":{"type":"integer","maximum":3650.0,"minimum":1.0,"title":"Period Days","default":30},"external_payment_id":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"External Payment Id"}},"type":"object","title":"CreateConfigRequest","example":{"domain":"monetto.devasvarupa.ru","external_payment_id":"order_2026_0001","period_days":30,"uid":"265c8f2d-7431-40e1-b5da-22630a235e6d"}},"CreateConfigResponse":{"properties":{"uid":{"type":"string","title":"Uid"},"domain":{"type":"string","title":"Domain"},"status":{"type":"string","title":"Status"},"paid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paid Until"},"suspended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Suspended At"},"config":{"type":"object","title":"Config"},"gateway_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gateway Url"},"legacy_config_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legacy Config Url"},"remnawave":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Remnawave"},"amnezia":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Amnezia"}},"type":"object","required":["uid","domain","status","paid_until","suspended_at","config"],"title":"CreateConfigResponse"},"CreateMonettoSubscriptionRequest":{"properties":{"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain","description":"Domain key. Optional for /api/v2/monetto/subscriptions (will fallback to request host)."},"subscription_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Id","description":"Local subscription id. If empty, generated on server."},"period_days":{"type":"integer","maximum":3650.0,"minimum":1.0,"title":"Period Days","default":30},"external_payment_id":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"External Payment Id","description":"Required Monetto payment idempotency key. Reusing it returns the existing access without extending twice."},"tg_username":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Tg Username","description":"Required Telegram username for Monetto payments. Accepted formats: `username` or `@username`; stored normalized without `@`."}},"type":"object","title":"CreateMonettoSubscriptionRequest","example":{"domain":"monetto.devasvarupa.ru","external_payment_id":"monetto_order_123","period_days":30,"subscription_id":"265c8f2d-7431-40e1-b5da-22630a235e6d","tg_username":"username"}},"GetConfigResponse":{"properties":{"uid":{"type":"string","title":"Uid"},"domain":{"type":"string","title":"Domain"},"status":{"type":"string","title":"Status"},"paid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paid Until"},"suspended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Suspended At"},"config":{"type":"object","title":"Config"},"gateway_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gateway Url"},"legacy_config_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legacy Config Url"},"remnawave":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Remnawave"},"amnezia":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Amnezia"}},"type":"object","required":["uid","domain","status","paid_until","suspended_at","config"],"title":"GetConfigResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"MonettoAmneziaResponse":{"properties":{"vpn_key_available":{"type":"boolean","title":"Vpn Key Available","default":false},"awg_config_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Awg Config Url"},"qr_available":{"type":"boolean","title":"Qr Available","default":false}},"type":"object","title":"MonettoAmneziaResponse"},"MonettoRemnawaveResponse":{"properties":{"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"subscription_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Url"},"user_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Uuid"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},"type":"object","title":"MonettoRemnawaveResponse"},"MonettoSubscriptionResponse":{"properties":{"subscription_id":{"type":"string","title":"Subscription Id"},"device_uid":{"type":"string","title":"Device Uid"},"domain":{"type":"string","title":"Domain"},"status":{"type":"string","title":"Status"},"paid_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Paid Until"},"tg_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tg Username"},"gateway_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gateway Url"},"legacy_config_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legacy Config Url"},"remnawave":{"anyOf":[{"$ref":"#/components/schemas/MonettoRemnawaveResponse"},{"type":"null"}]},"amnezia":{"anyOf":[{"$ref":"#/components/schemas/MonettoAmneziaResponse"},{"type":"null"}]}},"type":"object","required":["subscription_id","device_uid","domain","status","paid_until"],"title":"MonettoSubscriptionResponse"},"PauseConfigRequest":{"properties":{"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","default":"paused_by_site"}},"type":"object","title":"PauseConfigRequest","example":{"reason":"payment_expired"}},"PauseConfigResponse":{"properties":{"uid":{"type":"string","title":"Uid"},"domain":{"type":"string","title":"Domain"},"status":{"type":"string","title":"Status"},"paused_at":{"type":"string","format":"date-time","title":"Paused At"}},"type":"object","required":["uid","domain","status","paused_at"],"title":"PauseConfigResponse"},"PauseMonettoSubscriptionResponse":{"properties":{"subscription_id":{"type":"string","title":"Subscription Id"},"domain":{"type":"string","title":"Domain"},"status":{"type":"string","title":"Status"},"paused_at":{"type":"string","format":"date-time","title":"Paused At"}},"type":"object","required":["subscription_id","domain","status","paused_at"],"title":"PauseMonettoSubscriptionResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"site-api","description":"Payment-site integration endpoints"}]}