{
 "openapi": "3.1.0",
 "info": {
  "title": "Tino API (gateway /v1)",
  "version": "v1",
  "description": "Call the Tino API on behalf of a customer: https://developers.tino.vn/en/docs/api"
 },
 "servers": [
  {
   "url": "https://api.tino.vn"
  }
 ],
 "components": {
  "securitySchemes": {
   "oauth": {
    "type": "oauth2",
    "description": "Đăng nhập bằng Tino: access token tinoat_",
    "flows": {
     "authorizationCode": {
      "authorizationUrl": "https://auth.tino.vn/oauth/consent",
      "tokenUrl": "https://api.tino.vn/oauth/token",
      "refreshUrl": "https://api.tino.vn/oauth/token",
      "scopes": {
       "profile:read": "View account details",
       "profile:write": "Edit account details",
       "services:read": "View services, including service login details",
       "services:write": "Service management",
       "domains:read": "View domains",
       "domains:write": "Domain management",
       "dns:read": "View DNS records",
       "dns:write": "Edit DNS records",
       "billing:read": "View invoices and payments",
       "billing:write": "Make payments and top up",
       "tickets:read": "View support tickets",
       "tickets:write": "Create and reply to tickets"
      }
     }
    }
   },
   "personalToken": {
    "type": "http",
    "scheme": "bearer",
    "description": "Token API cá nhân tinopat_ (https://developers.tino.vn/docs/personal-tokens)"
   },
   "session": {
    "type": "http",
    "scheme": "bearer",
    "description": "TinoPay, Tino Uptime, TinoPage Builder: token đăng nhập của chủ dịch vụ (https://developers.tino.vn/docs/tinopay-start, https://developers.tino.vn/docs/uptime-start, https://developers.tino.vn/docs/builder-start)"
   }
  }
 },
 "paths": {
  "/v1/clientarea": {
   "get": {
    "operationId": "get_clientarea",
    "summary": "Account overview",
    "description": "Counts of invoices, domains, tickets and services of the account.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-clientarea"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "total": {
          "invoices": 1,
          "domains": 1,
          "tickets": 3,
          "services": 3
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/clientarea/nav/service": {
   "get": {
    "operationId": "get_clientarea_nav_service",
    "summary": "Service categories",
    "description": "Categories and subcategories of service types, used to build the services menu.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-clientarea-nav-service"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/clientarea/search/{query}": {
   "post": {
    "operationId": "post_clientarea_search_query",
    "summary": "Search services and products",
    "description": "Search the account's services and products for the string `@query` (for example a domain name). Read-only, even though it is `POST`.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-clientarea-search-query"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [
     {
      "name": "query",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Text to search for"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/clientarea/statuses": {
   "get": {
    "operationId": "get_clientarea_statuses",
    "summary": "List statuses",
    "description": "Status values of invoices, domains, tickets, services and estimates.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-clientarea-statuses"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "invoice": [
          "Paid",
          "Unpaid",
          "… 4 more item(s)"
         ],
         "domain": [
          "Pending",
          "Active",
          "… 4 more item(s)"
         ],
         "ticket": [
          "Open",
          "Closed",
          "… 4 more item(s)"
         ],
         "service": [
          "Pending",
          "Active",
          "… 4 more item(s)"
         ],
         "estimates": [
          "Draft",
          "Sent",
          "… 3 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/contact": {
   "get": {
    "operationId": "get_contact",
    "summary": "List contacts",
    "description": "The account's contacts (sub-accounts).",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-contact"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "contacts": null,
         "page": {
          "current": 0,
          "total": 0
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/contact/{id}": {
   "get": {
    "operationId": "get_contact_id",
    "summary": "Contact details",
    "description": "Details and permissions of a contact.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-contact-id"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Contact ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/contact/privileges": {
   "get": {
    "operationId": "get_contact_privileges",
    "summary": "Permissions available for contacts",
    "description": "Permissions that can be granted to contacts. Each domain and service may have additional permissions, depending on its features.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-contact-privileges"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/contacts": {
   "get": {
    "operationId": "get_contacts",
    "summary": "List contacts (contacts)",
    "description": "The account's contacts (sub-accounts).",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-contacts"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "contacts": null,
         "page": {
          "current": 0,
          "total": 0
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/details": {
   "get": {
    "operationId": "get_details",
    "summary": "Account details",
    "description": "Registration details of the account.\n\n`verify.phone` (bool) and the `phone` block `{status, verified_at}` show the phone number status; `status` is `verified`, `unverified`, `taken_by_other` or `missing`. `update_required` at the root refers to the profile (ID document number, address), not the phone number.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-details"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "client": {
          "id": "700001",
          "group_id": "0",
          "email": "user@example.com",
          "lastlogin": "2026-08-02 10:00:00",
          "ip": "203.0.113.10",
          "host": "host.example",
          "firstname": "Nguyen Van",
          "lastname": "A",
          "companyname": "Example Company Ltd",
          "address1": "123 Example Street",
          "city": "Phường Bến Thành",
          "state": "Thành phố Hồ Chí Minh",
          "country": "VN",
          "phonenumber": "+84.900000000",
          "language": "vietnamese",
          "company": false,
          "currency_id": "0",
          "taxid": "0100000000",
          "nationalid": "000000000000",
          "birthday": "01/01/1990",
          "…": "3 more key(s)"
         },
         "update_required": true,
         "currency": {
          "code": "đ",
          "iso": "VND",
          "sign": "",
          "format": "1,234.56",
          "decimal": "0",
          "id": 0
         },
         "verify": {
          "email": "user@example.com"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/notifications": {
   "get": {
    "operationId": "get_notifications",
    "summary": "List notifications",
    "description": "All notifications on the account's control panel.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-notifications"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [
     {
      "name": "rel_type",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Optional, return only by relation type"
      }
     },
     {
      "name": "rel_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Optional, return only by relation id"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "notifications": [
          {
           "id": 920001,
           "client_id": "<redacted>",
           "rel_type": "account",
           "rel_id": "100001",
           "seen": "0",
           "subject": "Thông tin tài khoản Hosting tại TinoGroup.",
           "body": "Dear Nguyen Van A,<br />\n<br />\nTh&ocirc;ng tin t&agrave;i khoản hosting của bạn đ&atilde; được khởi tạo.<br />\n<br />\nTh&ocirc;ng tin dịch vụ<br />\n<br />\nDịch vụ: WH 1<br />\nT&ecirc;n miền: example.com<br />\nThanh to&aacute;n lần đầu: 79,000 đ<br />\nThanh to&aacute;n gia hạn: 79,000 đ<br …",
           "metadata": "[]",
           "type": "direct",
           "date_added": "2026-07-26 10:00:00",
           "date_seen": null,
           "url": false
          },
          {
           "id": 171464,
           "client_id": "<redacted>",
           "rel_type": "ticket",
           "rel_id": "445776",
           "seen": "0",
           "subject": "Nhân viên hỗ trợ đã phản hồi ticket",
           "body": "On 24 Jul 2026, at 20:18, Nguyen Van A &lt;user@example.com&gt; wrote:  Nơi tiếp nhận những y&ecirc;u cầu hỗ trợ bản khai, x&aacute;c thực t&ecirc;n miền. Kh&aacute;ch h&agrave;ng c&oacute; thể li&ecirc;n hệ trực tiếp qua hotline 0364.333.333 nhấn ph&iacute;m 2 \n\nBest Regards!\n\n/----------------…",
           "metadata": "[]",
           "type": "direct",
           "date_added": "2026-07-24 10:00:00",
           "date_seen": null,
           "url": false
          },
          "… 12 more item(s)"
         ],
         "page": {
          "total": 14,
          "pages": 1,
          "current": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/notifications/{id}/ack": {
   "put": {
    "operationId": "put_notifications_id_ack",
    "summary": "Mark notification as read",
    "description": "Mark notification `@id` as read. Also send `seen_all=true` to mark all notifications as read.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-notifications-id-ack"
    },
    "security": [
     {
      "oauth": [
       "profile:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Notification ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "id": "171464",
         "success": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/notifications/new": {
   "get": {
    "operationId": "get_notifications_new",
    "summary": "Unread notifications",
    "description": "Only new (unread) notifications.",
    "tags": [
     "Account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-notifications-new"
    },
    "security": [
     {
      "oauth": [
       "profile:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "profile:read",
    "parameters": [
     {
      "name": "rel_type",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Optional, return only by relation type"
      }
     },
     {
      "name": "rel_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Optional, return only by relation id"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "notifications": [
          {
           "id": 920001,
           "rel_type": "account",
           "rel_id": "100001",
           "seen": "0",
           "subject": "Thông tin tài khoản Hosting tại TinoGroup.",
           "body": "Dear Nguyen Van A,<br />\n<br />\nTh&ocirc;ng tin t&agrave;i khoản hosting của bạn đ&atilde; được khởi tạo.<br />\n<br />\nTh&ocirc;ng tin dịch vụ<br />\n<br />\nDịch vụ: WH 1<br />\nT&ecirc;n miền: example.com<br />\nThanh to&aacute;n lần đầu: 79,000 đ<br />\nThanh to&aacute;n gia hạn: 79,000 đ<br …",
           "metadata": "[]",
           "date_added": "2026-07-26 10:00:00",
           "date_seen": null,
           "url": false
          },
          {
           "id": 171464,
           "rel_type": "ticket",
           "rel_id": "445776",
           "seen": "0",
           "subject": "Nhân viên hỗ trợ đã phản hồi ticket",
           "body": "On 24 Jul 2026, at 20:18, Nguyen Van A &lt;user@example.com&gt; wrote:  Nơi tiếp nhận những y&ecirc;u cầu hỗ trợ bản khai, x&aacute;c thực t&ecirc;n miền. Kh&aacute;ch h&agrave;ng c&oacute; thể li&ecirc;n hệ trực tiếp qua hotline 0364.333.333 nhấn ph&iacute;m 2 \n\nBest Regards!\n\n/----------------…",
           "metadata": "[]",
           "date_added": "2026-07-24 10:00:00",
           "date_seen": null,
           "url": false
          },
          "… 12 more item(s)"
         ],
         "success": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service": {
   "get": {
    "operationId": "get_service",
    "summary": "List services",
    "description": "All services of the account.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "services": [
          {
           "id": "100001",
           "domain": "example.com",
           "total": "79000.00",
           "status": "Active",
           "billingcycle": "Monthly",
           "next_due": "2026-08-26",
           "expires": "2026-08-26",
           "category": "Platinum Hosting",
           "category_url": "platinum-hosting",
           "name": "WH 1"
          },
          {
           "id": "100002",
           "domain": "vps-demo.example.net",
           "total": "199000.00",
           "status": "Active",
           "billingcycle": "Monthly",
           "next_due": "2026-08-26",
           "expires": "2026-08-26",
           "category": "NVMe VPS ",
           "category_url": "nvme-vps",
           "name": "VPS 20 GB NVMe"
          },
          "… 9 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}": {
   "get": {
    "operationId": "get_service_id",
    "summary": "Service details",
    "description": "Details of service `@id`: plan, billing cycle, expiry, status, service login details.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "service": {
          "id": "100001",
          "product_id": "2122",
          "date_created": "2026-07-26",
          "domain": "example.com",
          "firstpayment": "79000.00",
          "total": "79000.00",
          "billingcycle": "Monthly",
          "next_due": "2026-08-26",
          "due_day": "26",
          "expires": "2026-08-26",
          "autorenew": "1",
          "next_invoice": "2026-08-11",
          "status": "Active",
          "label": "",
          "username": "exampleuser",
          "password": "<redacted>",
          "rootpassword": null,
          "commitment_date": null,
          "date_suspended": "0000-00-00",
          "date_terminated": "0000-00-00",
          "…": "9 more key(s)"
         },
         "addons": [],
         "haveaddons": [],
         "unpaid_invoice": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/cancel": {
   "post": {
    "operationId": "post_service_id_cancel",
    "summary": "Request service cancellation",
    "description": "Send a request to cancel the service.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-cancel"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "immediate": {
          "type": "string",
          "description": "set to false to terminate service at the end of billing date, true - terminate immediately"
         },
         "reason": {
          "type": "string",
          "description": "Reason for this request"
         }
        },
        "required": []
       },
       "example": {
        "immediate": "<immediate>",
        "reason": "<reason>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "info": [
          "cancell_sent"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/cycle": {
   "get": {
    "operationId": "get_service_id_cycle",
    "summary": "Billing cycles",
    "description": "The current billing cycle and the cycles it can be changed to.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-cycle"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "current": "m",
         "cycles": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_service_id_cycle",
    "summary": "Change billing cycle",
    "description": "Change the service's recurring billing cycle.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-cycle"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "cycle": {
          "type": "string",
          "description": "New billing cycle"
         }
        },
        "required": []
       },
       "example": {
        "cycle": "<cycle>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/emails": {
   "get": {
    "operationId": "get_service_id_emails",
    "summary": "Hosting email accounts",
    "description": "Email accounts on the service's cPanel hosting (`listentrys`).",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-emails"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "Name",
      "in": "In",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Description"
      }
     },
     {
      "name": "---",
      "in": "---",
      "required": false,
      "schema": {
       "type": "string",
       "description": "---"
      }
     },
     {
      "name": "module",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service type module (Cpanel2|DirectAdmin2|Zimbra|Wilduck)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "listentrys": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/invoices": {
   "get": {
    "operationId": "get_service_id_invoices",
    "summary": "Service invoices",
    "description": "Invoices related to the service (`rel_invoices`).",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-invoices"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "rel_invoices": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/label": {
   "get": {
    "operationId": "get_service_id_label",
    "summary": "Get service label",
    "description": "The service's current custom label.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-label"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "label": ""
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_service_id_label",
    "summary": "Set service label",
    "description": "Set a custom label to identify the service.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-label"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "label": {
          "type": "string",
          "description": "New label"
         }
        },
        "required": []
       },
       "example": {
        "label": "<label>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "info": [
          "service_label_updated"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/manualrenew": {
   "post": {
    "operationId": "post_service_id_manualrenew",
    "summary": "Create service renewal invoice",
    "description": "Create a renewal invoice for the service. If the service already has an unpaid invoice, returns that invoice's `invoice_id`; if the service has a pending upgrade, returns an error.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-manualrenew"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "invoice_id": null,
         "info": [
          "manualrenew_ok"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/methods": {
   "get": {
    "operationId": "get_service_id_methods",
    "summary": "Supported service actions",
    "description": "Routes that can be used with this service (name, method, path).",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-methods"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "methods": [
          {
           "name": "Upgrade Options",
           "method": "GET",
           "route": "/service/@id/upgrade"
          },
          {
           "name": "Upgrade Request",
           "method": "POST",
           "route": "/service/@id/upgrade"
          },
          "… 30 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/renew": {
   "post": {
    "operationId": "post_service_id_renew",
    "summary": "Renew service",
    "description": "Create a renewal invoice for the service.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-renew"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/upgrade": {
   "get": {
    "operationId": "get_service_id_upgrade",
    "summary": "Upgrade options",
    "description": "Plans and resources available for upgrade, with prices per billing cycle.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-upgrade"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "resources": [],
         "package": [
          {
           "id": "2007",
           "name": "Host 5GB NVMe",
           "category": "Hosting NVMe",
           "price": {
            "Monthly": "79000.00",
            "Quarterly": "237000.00",
            "Semi-Annually": "474000.00",
            "Annually": "853200.00",
            "Biennially": "1611600.00",
            "Triennially": "2275200.00",
            "Quadrennially": "2844000.00",
            "Quinquennially": "3318000.00"
           }
          },
          {
           "id": "2008",
           "name": "Host Starter NVMe",
           "category": "Hosting NVMe",
           "price": {
            "Monthly": "339000.00",
            "Quarterly": "1017000.00",
            "Semi-Annually": "1830600.00",
            "Annually": "3254400.00",
            "Biennially": "5695200.00",
            "Triennially": "7322400.00",
            "Quadrennially": "8136000.00",
            "Quinquennially": "9153000.00"
           }
          },
          "… 6 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_service_id_upgrade",
    "summary": "Upgrade quote or request",
    "description": "Calculate the upgrade price; send `send=true` to submit the upgrade request.\n\nFormat of the `resources` parameter:\n\n```json\n{\n  \"resource_id\": \"qty_value\",\n  \"resource_id\": \"item_id\",\n  \"resource_id\": { \"item_id\": \"qty_value\" }\n}\n```\n\n- `\"qty_value\"`: sliders and quantity fields\n- `\"item_id\"`: select lists and radio buttons\n- `{ \"item_id\": \"qty_value\" }`: select lists with a quantity field",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-upgrade"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "resources": {
          "type": "array",
          "description": "array with resource values"
         },
         "package": {
          "type": "integer",
          "description": "New package id, optonal when upgrading resources"
         },
         "cycle": {
          "type": "string",
          "description": "New billing cycle, optonal when upgrading resources"
         },
         "send": {
          "type": "boolean",
          "description": "Set to true when you want to send your upgrade request"
         }
        },
        "required": []
       },
       "example": {
        "resources": "<resources>",
        "package": "<package>",
        "cycle": "<cycle>",
        "send": "<send>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/widgets": {
   "get": {
    "operationId": "get_service_id_widgets",
    "summary": "Service widgets",
    "description": "The service's widgets.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-widgets"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "methods": [
          {
           "name": "Upgrade Options",
           "method": "GET",
           "route": "/service/@id/upgrade"
          },
          {
           "name": "Upgrade Request",
           "method": "POST",
           "route": "/service/@id/upgrade"
          },
          "… 30 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/cpanel2/{id}/statistics": {
   "get": {
    "operationId": "get_service_cpanel2_id_statistics",
    "summary": "cPanel statistics",
    "description": "Disk space, bandwidth and other usage metrics of cPanel hosting, keyed by each metric's `id`.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-cpanel2-id-statistics"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "cPanel hosting service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/cpanel2/{id}/unblock": {
   "post": {
    "operationId": "post_service_cpanel2_id_unblock",
    "summary": "Unblock IP on cPanel",
    "description": "Unblock an IP on the firewall of the cPanel server that hosts the service. Returns `block` and `myip`.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-cpanel2-id-unblock"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "cPanel hosting service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/services/{cid}": {
   "get": {
    "operationId": "get_services_cid",
    "summary": "Services by category",
    "description": "The account's services in category `@cid` (`0`: all categories).\n\nFilters: `filter[hide_terminated]=1`, `filter[hide_cancelled]=1`, `filter[hide_suspended]=1`, `filter[hide_fraud]=1`, `filter[status]=Active`.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-services-cid"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "cid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service category ID; `0`: all categories"
      }
     },
     {
      "name": "Name",
      "in": "In",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Description"
      }
     },
     {
      "name": "---",
      "in": "---",
      "required": false,
      "schema": {
       "type": "string",
       "description": "---"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "services": [
          {
           "id": "100001",
           "domain": "example.com",
           "total": "79000.00",
           "status": "Active",
           "billingcycle": "Monthly",
           "next_due": "2026-08-26",
           "category": "Platinum Hosting",
           "category_url": "platinum-hosting",
           "name": "WH 1"
          },
          {
           "id": "100002",
           "domain": "vps-demo.example.net",
           "total": "199000.00",
           "status": "Active",
           "billingcycle": "Monthly",
           "next_due": "2026-08-26",
           "category": "NVMe VPS ",
           "category_url": "nvme-vps",
           "name": "VPS 20 GB NVMe"
          },
          "… 1 more item(s)"
         ],
         "total": 3,
         "page": {
          "current": 0,
          "total": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/services/active": {
   "get": {
    "operationId": "get_services_active",
    "summary": "Active services",
    "description": "The account's active services.",
    "tags": [
     "Services"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-services-active"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "services": [
          {
           "id": "100001",
           "domain": "example.com",
           "total": "79000.00",
           "status": "Active",
           "billingcycle": "Monthly",
           "next_due": "2026-08-26",
           "category": "Platinum Hosting",
           "category_url": "platinum-hosting",
           "name": "WH 1"
          },
          {
           "id": "100002",
           "domain": "vps-demo.example.net",
           "total": "199000.00",
           "status": "Active",
           "billingcycle": "Monthly",
           "next_due": "2026-08-26",
           "category": "NVMe VPS ",
           "category_url": "nvme-vps",
           "name": "VPS 20 GB NVMe"
          },
          "… 1 more item(s)"
         ],
         "total": 3,
         "page": {
          "current": 0,
          "total": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/networks": {
   "get": {
    "operationId": "get_service_id_networks",
    "summary": "Networks and IP ranges",
    "description": "Networks and IP ranges available when creating virtual machines.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-networks"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/resources": {
   "get": {
    "operationId": "get_service_id_resources",
    "summary": "VPS resources",
    "description": "Free and used resources (CPU, RAM, disk, IP).",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-resources"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "limit": {
          "mem": 0,
          "cpu": 0,
          "ips": 0,
          "priv_ips": 0,
          "disk": 0,
          "additional_storage": 0
         },
         "total": {
          "cpu": 1,
          "mem": 1024,
          "ips": 1,
          "priv_ips": 0,
          "disk": 20,
          "additional_storage": 0
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/templates": {
   "get": {
    "operationId": "get_service_id_templates",
    "summary": "OS templates",
    "description": "Operating system templates used to create virtual machines.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-templates"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "templates": [
          {
           "id": "a37411b5-4136-29f6-9dc0-d07f78a6ad5e",
           "name": "Ubuntu 26.04",
           "price": 0,
           "type": "template",
           "group": "public",
           "size_gb": 4,
           "interfaces": [
            {
             "name": "net0",
             "zones": null,
             "zone": "vmbr0",
             "ip_required": true
            }
           ]
          },
          {
           "id": "8c93b9af-1bd8-5a73-8190-f7e272bd4157",
           "name": "Almalinux 10",
           "price": 0,
           "type": "template",
           "group": "public",
           "size_gb": 10,
           "interfaces": [
            {
             "name": "net0",
             "zones": null,
             "zone": "vmbr0",
             "ip_required": true
            }
           ]
          },
          "… 12 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms": {
   "get": {
    "operationId": "get_service_id_vms",
    "summary": "List virtual machines",
    "description": "Virtual machines of the VPS service.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-vms"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "vms": {
          "600001": {
           "id": 600001,
           "ha": false,
           "built": true,
           "locked": false,
           "power": true,
           "status": "running",
           "status_lang": "vm_state_running",
           "password": "<redacted>",
           "sshkeys": [
            "ssh-ed25519 AAAA<public-key> user@example.com"
           ],
           "username": "root",
           "memory": 1024,
           "disk": 20,
           "swap": null,
           "additional_storage": [],
           "uptime": 639603,
           "template_id": "template-vm:321/321/base-321-disk-0.raw",
           "template_name": "Ubuntu 26.04",
           "template_data": [],
           "replication": false,
           "cloudinit": true,
           "…": "14 more key(s)"
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}": {
   "get": {
    "operationId": "get_service_id_vms_vmid",
    "summary": "Virtual machine details",
    "description": "Details of a virtual machine: status, resources, OS template, SSH keys.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-vms-vmid"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "vm": {
          "id": 600001,
          "ha": false,
          "built": true,
          "locked": false,
          "power": true,
          "status": "running",
          "status_lang": "vm_state_running",
          "password": "<redacted>",
          "sshkeys": [
           "ssh-ed25519 AAAA<public-key> user@example.com"
          ],
          "username": "root",
          "memory": 1024,
          "disk": 20,
          "swap": null,
          "additional_storage": [],
          "uptime": 639639,
          "template_id": "template-vm:321/321/base-321-disk-0.raw",
          "template_name": "Ubuntu 26.04",
          "template_data": [],
          "replication": false,
          "cloudinit": true,
          "…": "14 more key(s)"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/hostname": {
   "post": {
    "operationId": "post_service_id_vms_vmid_hostname",
    "summary": "Change VM hostname",
    "description": "Change the virtual machine's hostname.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-vms-vmid-hostname"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "server_name": {
          "type": "string",
          "description": "Virtual server name"
         }
        },
        "required": [
         "server_name"
        ]
       },
       "example": {
        "server_name": "<server_name>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "status": 1
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/interfaces": {
   "get": {
    "operationId": "get_service_id_vms_vmid_interfaces",
    "summary": "VM network interfaces",
    "description": "Network interfaces attached to the virtual machine, with their IPs.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-vms-vmid-interfaces"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": [
         {
          "id": 0,
          "name": "net0",
          "model": "virtio",
          "mac": "02:00:00:00:00:01",
          "firewall": "1",
          "ip": [
           {
            "id": 930001,
            "interface": 0,
            "mac": "02:00:00:00:00:01",
            "ip": "203.0.113.10",
            "wanip": "",
            "mask": "/24",
            "network": "203.0.113.10",
            "gateway": "203.0.113.10",
            "main": 1,
            "type": "ipv4"
           },
           {
            "id": 27930,
            "interface": 0,
            "mac": "02:00:00:00:00:01",
            "ip": "203.0.113.10",
            "wanip": "",
            "mask": "/64",
            "network": "2001:db8::1",
            "gateway": "2001:db8::1",
            "main": 1,
            "type": "ipv6"
           }
          ],
          "bridge": "vmbr0",
          "vlan": "136",
          "link_down": null,
          "can_edit": true,
          "can_remove": false
         }
        ]
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/interfaces/{iface}": {
   "get": {
    "operationId": "get_service_id_vms_vmid_interfaces_iface",
    "summary": "Network interface details",
    "description": "Details of one network interface of the virtual machine.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-vms-vmid-interfaces-iface"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     },
     {
      "name": "iface",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Network interface name or number, e.g. `0` or `net0`"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": []
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/ippool": {
   "get": {
    "operationId": "get_service_id_vms_vmid_ippool",
    "summary": "VM IP pools",
    "description": "IP pools for a network interface or a network bridge.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-vms-vmid-ippool"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     },
     {
      "name": "Name",
      "in": "In",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Description"
      }
     },
     {
      "name": "---",
      "in": "---",
      "required": false,
      "schema": {
       "type": "string",
       "description": "---"
      }
     },
     {
      "name": "iface",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Interface number [optional]"
      }
     },
     {
      "name": "bridge",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Bridge name [optional, ignored if interface provided]"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": [
         {
          "id": "public",
          "name": "Public IP(s)",
          "type": "ipv4",
          "vlan_id": "41",
          "firstip": "203.0.113.10",
          "mask": "/24",
          "gateway": "203.0.113.10"
         },
         {
          "id": "public",
          "name": "Public IP(s)",
          "type": "ipv6",
          "vlan_id": "42",
          "firstip": "2001:db8::",
          "mask": "/64",
          "gateway": "2001:db8::1"
         }
        ]
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/ips": {
   "get": {
    "operationId": "get_service_id_vms_vmid_ips",
    "summary": "VM IP addresses",
    "description": "IP addresses of the virtual machine.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-vms-vmid-ips"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     },
     {
      "name": "Name",
      "in": "In",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Description"
      }
     },
     {
      "name": "---",
      "in": "---",
      "required": false,
      "schema": {
       "type": "string",
       "description": "---"
      }
     },
     {
      "name": "type",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "ipv4 or ipv6"
      }
     },
     {
      "name": "iface",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Interface number [optional]"
      }
     },
     {
      "name": "bridge",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Bridge name [optional, ignored if interface provided]"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": [
         {
          "id": 930001,
          "interface": 0,
          "mac": "02:00:00:00:00:01",
          "ip": "203.0.113.10",
          "wanip": "",
          "mask": "/24",
          "network": "203.0.113.10",
          "gateway": "203.0.113.10",
          "main": 1,
          "type": "ipv4"
         },
         {
          "id": 27930,
          "interface": 0,
          "mac": "02:00:00:00:00:01",
          "ip": "203.0.113.10",
          "wanip": "",
          "mask": "/64",
          "network": "2001:db8::1",
          "gateway": "2001:db8::1",
          "main": 1,
          "type": "ipv6"
         }
        ]
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/reboot": {
   "post": {
    "operationId": "post_service_id_vms_vmid_reboot",
    "summary": "Restart VM",
    "description": "Restart the virtual machine.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-vms-vmid-reboot"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/reset": {
   "post": {
    "operationId": "post_service_id_vms_vmid_reset",
    "summary": "Reset VM",
    "description": "Power-reset the virtual machine (like unplugging it and plugging it back in).",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-vms-vmid-reset"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "status": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/shutdown": {
   "post": {
    "operationId": "post_service_id_vms_vmid_shutdown",
    "summary": "Shut down VM",
    "description": "Shut down the virtual machine normally (sends a shutdown command to the operating system).",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-vms-vmid-shutdown"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "status": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/start": {
   "post": {
    "operationId": "post_service_id_vms_vmid_start",
    "summary": "Start VM",
    "description": "Start the virtual machine.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-vms-vmid-start"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "status": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/stop": {
   "post": {
    "operationId": "post_service_id_vms_vmid_stop",
    "summary": "Stop VM",
    "description": "Stop the virtual machine immediately.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-vms-vmid-stop"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "status": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/vms/{vmid}/traffic": {
   "get": {
    "operationId": "get_service_id_vms_vmid_traffic",
    "summary": "VM network traffic",
    "description": "Network traffic of the virtual machine.",
    "tags": [
     "VPS servers"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-vms-vmid-traffic"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "vmid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Virtual machine ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/certificate": {
   "get": {
    "operationId": "get_certificate",
    "summary": "List SSL certificates",
    "description": "All SSL certificate services of the account.",
    "tags": [
     "SSL certificates"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-certificate"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/certificate/{id}": {
   "get": {
    "operationId": "get_certificate_id",
    "summary": "SSL certificate details",
    "description": "Details of SSL certificate service `@id`.",
    "tags": [
     "SSL certificates"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-certificate-id"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "SSL certificate service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "products": [
          {
           "id": "26",
           "name": "Comodo PositiveSSL",
           "description": "<ul></ul>",
           "category": "Comodo SSL",
           "category_url": "comodo-ssl",
           "periods": [
            {
             "years": 1,
             "price": 175000,
             "renew": 175000
            },
            {
             "years": 2,
             "price": 297600,
             "renew": 297600
            },
            "… 1 more item(s)"
           ]
          },
          {
           "id": "27",
           "name": "Comodo PositiveSSL Wildcard",
           "description": "<ul></ul>",
           "category": "Comodo SSL",
           "category_url": "comodo-ssl",
           "periods": [
            {
             "years": 1,
             "price": 2139000,
             "renew": 2139000
            },
            {
             "years": 2,
             "price": 4278000,
             "renew": 4278000
            },
            "… 1 more item(s)"
           ]
          },
          "… 12 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/certificate/{id}/crt": {
   "get": {
    "operationId": "get_certificate_id_crt",
    "summary": "Download certificate",
    "description": "X.509 certificate data of the service.",
    "tags": [
     "SSL certificates"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-certificate-id-crt"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "SSL certificate service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": []
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/certificate/order": {
   "get": {
    "operationId": "get_certificate_order",
    "summary": "Certificates available to order",
    "description": "SSL certificate types on sale, with prices per number of years.",
    "tags": [
     "SSL certificates"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-certificate-order"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "products": [
          {
           "id": "26",
           "name": "Comodo PositiveSSL",
           "description": "<ul></ul>",
           "category": "Comodo SSL",
           "category_url": "comodo-ssl",
           "periods": [
            {
             "years": 1,
             "price": 175000,
             "renew": 175000
            },
            {
             "years": 2,
             "price": 297600,
             "renew": 297600
            },
            "… 1 more item(s)"
           ]
          },
          {
           "id": "27",
           "name": "Comodo PositiveSSL Wildcard",
           "description": "<ul></ul>",
           "category": "Comodo SSL",
           "category_url": "comodo-ssl",
           "periods": [
            {
             "years": 1,
             "price": 2139000,
             "renew": 2139000
            },
            {
             "years": 2,
             "price": 4278000,
             "renew": 4278000
            },
            "… 1 more item(s)"
           ]
          },
          "… 12 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_certificate_order",
    "summary": "Order SSL certificate",
    "description": "Create a standalone SSL certificate order.",
    "tags": [
     "SSL certificates"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-certificate-order"
    },
    "security": [
     {
      "oauth": [
       "services:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "product_id": {
          "type": "integer",
          "description": "Certificate product ID"
         },
         "csr": {
          "type": "string",
          "description": "Domain name"
         },
         "years": {
          "type": "integer",
          "description": "Number of years"
         },
         "pay_method": {
          "type": "integer",
          "description": "Payment method ID"
         },
         "approver_email": {
          "type": "string",
          "description": "Email addres used in domain validation"
         },
         "admin": {
          "type": "integer",
          "description": "Admin contact ID"
         },
         "tech": {
          "type": "integer",
          "description": "Tech contact ID"
         },
         "billing": {
          "type": "integer",
          "description": "Billing contact ID"
         },
         "organization": {
          "type": "array",
          "description": "Organization details"
         },
         "software": {
          "type": "integer",
          "description": "Server/Software ID"
         },
         "data": {
          "type": "array",
          "description": "Addditional data required for some products"
         },
         "aff_id": {
          "type": "integer",
          "description": "Affiliate ID"
         }
        },
        "required": []
       },
       "example": {
        "product_id": "<product_id>",
        "csr": "example.com",
        "years": "<years>",
        "pay_method": "<pay_method>",
        "approver_email": "<approver_email>",
        "admin": "<admin>",
        "tech": "<tech>",
        "billing": "<billing>",
        "organization": "<organization>",
        "software": "<software>",
        "data": "<data>",
        "aff_id": 55
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/certificate/order/{product_id}/software": {
   "get": {
    "operationId": "get_certificate_order_product_id_software",
    "summary": "Server software for certificates",
    "description": "List of server software (the IDs are used when ordering a certificate).",
    "tags": [
     "SSL certificates"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-certificate-order-product-id-software"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "product_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Product ID (service plan, certificate)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "software": [
          {
           "id": 1,
           "name": "Apache + MOD SSL"
          },
          {
           "id": 2,
           "name": "Apache + Raven"
          },
          "… 26 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/certificates": {
   "get": {
    "operationId": "get_certificates",
    "summary": "List SSL services (certificates)",
    "description": "All SSL certificate services of the account (`sslservices`).",
    "tags": [
     "SSL certificates"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-certificates"
    },
    "security": [
     {
      "oauth": [
       "services:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "services:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "sslservices": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain": {
   "get": {
    "operationId": "get_domain",
    "summary": "List domains",
    "description": "The account's domains.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domains": [
          {
           "id": "200001",
           "name": "example.com",
           "expires": "2026-12-07",
           "label": "",
           "recurring_amount": "585366.00",
           "date_created": "2025-12-07",
           "status": "Active",
           "period": "1",
           "idprotection": "1",
           "autorenew": "1",
           "daytoexpire": "127"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}": {
   "get": {
    "operationId": "get_domain_id",
    "summary": "Domain details",
    "description": "Domain details: expiry, nameservers, auto-renewal, lock, contacts.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/autorenew": {
   "get": {
    "operationId": "get_domain_id_autorenew",
    "summary": "Get domain auto-renewal",
    "description": "Whether auto-renewal is turned on for the domain.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-autorenew"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "allowrenew": null,
         "autorenew": "1"
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_domain_id_autorenew",
    "summary": "Turn domain auto-renewal on or off",
    "description": "Turn the domain's auto-renewal on or off.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-autorenew"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "autorenew": {
          "type": "boolean",
          "description": "true|false"
         }
        },
        "required": [
         "autorenew"
        ]
       },
       "example": {
        "autorenew": true
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "info": [
          "success_changes_save"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/contact": {
   "get": {
    "operationId": "get_domain_id_contact",
    "summary": "Get domain contacts",
    "description": "Registrant, administrative, technical and billing contact details of the domain.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-contact"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_domain_id_contact",
    "summary": "Change domain contacts (registrant)",
    "description": "Update the domain's contact details, including the registrant. Requires the `domains:owner` scope: only personal API tokens with an IP restriction.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-contact"
    },
    "security": [
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:owner",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "contact_info": {
          "type": "array"
         }
        },
        "required": []
       },
       "example": {
        "contact_info": "<contact_info>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/dnssec": {
   "get": {
    "operationId": "get_domain_id_dnssec",
    "summary": "List DNSSEC keys",
    "description": "DS records and DNSSEC keys of the domain.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-dnssec"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "ds_list": null,
         "key_list": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_domain_id_dnssec",
    "summary": "Add DNSSEC key",
    "description": "Add a DNSSEC key to the domain.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-dnssec"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "info": [
          "success_changes_save"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/dnssec/{key}": {
   "delete": {
    "operationId": "delete_domain_id_dnssec_key",
    "summary": "Delete DNSSEC key",
    "description": "Delete DNSSEC key `@key` of the domain.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-domain-id-dnssec-key"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     },
     {
      "name": "key",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "DNSSEC key to remove"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/dnssec/flags": {
   "get": {
    "operationId": "get_domain_id_dnssec_flags",
    "summary": "Supported DNSSEC parameters",
    "description": "Flag, protocol, algorithm and digest values used when adding a DNSSEC key.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-dnssec-flags"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "flag": null,
         "protocol": null,
         "algorithm": null,
         "digest": null,
         "form_type": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/emforwarding": {
   "get": {
    "operationId": "get_domain_id_emforwarding",
    "summary": "Get email forwarding",
    "description": "The domain's email forwarding rules.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-emforwarding"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domain_id": "200001",
         "email_forwarding": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_domain_id_emforwarding",
    "summary": "Update email forwarding",
    "description": "Set the domain's email forwarding rules.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-emforwarding"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "from": {
          "type": "string",
          "description": "Email address that you want to forward"
         },
         "to": {
          "type": "string",
          "description": "Email address that will receive forwarded emails"
         },
         "records": {
          "type": "array",
          "description": "Multiple forwarding rules [{\"from\":\"info\",\"to\":\"dest@example.com\"},{\"from\":\"support\",\"to\":\"help@example.com\"}]"
         }
        },
        "required": []
       },
       "example": {
        "from": "info@example.com",
        "to": "destination@example.com",
        "records": "<records>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "info": [
          "success_changes_save"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/epp": {
   "get": {
    "operationId": "get_domain_id_epp",
    "summary": "Get domain transfer code (EPP)",
    "description": "EPP code for transferring the domain to another registrar. Requires the `domains:owner` scope: only personal API tokens with an IP restriction.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-epp"
    },
    "security": [
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:owner",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domain_id": "200001",
         "epp_code": "<redacted>"
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/forwarding": {
   "put": {
    "operationId": "put_domain_id_forwarding",
    "summary": "Update domain forwarding",
    "description": "Set up forwarding for the domain.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-forwarding"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": []
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/idprotection": {
   "put": {
    "operationId": "put_domain_id_idprotection",
    "summary": "Turn registrant privacy on or off",
    "description": "Turn the domain's registrant information protection (ID Protection) on or off.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-idprotection"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "switch": {
          "type": "boolean",
          "description": "true|false"
         }
        },
        "required": []
       },
       "example": {
        "switch": "true|false"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/invoices": {
   "get": {
    "operationId": "get_domain_id_invoices",
    "summary": "Domain invoices",
    "description": "Invoices related to the domain (`rel_invoices`).",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-invoices"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "rel_invoices": [
          {
           "id": "300001",
           "client_id": "<redacted>",
           "date": "2026-03-30",
           "dateorig": "2026-03-30",
           "duedate": "2026-12-07",
           "paybefore": "2026-12-07",
           "currency_id": "0",
           "total": "574723.00",
           "paid_id": "",
           "subtotal": "532151.00",
           "tax": "42572.00",
           "tax2": "0.00",
           "datepaid": "0000-00-00 10:00:00",
           "status": "Unpaid",
           "merge_id": "300001"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/ns": {
   "get": {
    "operationId": "get_domain_id_ns",
    "summary": "Get nameservers",
    "description": "The nameservers the domain uses.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-ns"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domain_id": "200001",
         "nameservers": [
          "ns1.tino.vn",
          "ns2.tino.vn"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_domain_id_ns",
    "summary": "Change nameservers",
    "description": "Change the domain's nameservers; leave `nameservers` empty to use the default nameservers.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-ns"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "nameservers": {
          "type": "array",
          "description": "List of nameservers to use"
         }
        },
        "required": []
       },
       "example": {
        "nameservers": "<nameservers>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "info": [
          "success_changes_save"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/reg": {
   "get": {
    "operationId": "get_domain_id_reg",
    "summary": "Registered private nameservers",
    "description": "Private nameservers (glue records) registered under the domain. Not every registrar supports this; when it is not supported, the list may be empty.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-reg"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domain_id": "200001",
         "nameservers": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_domain_id_reg",
    "summary": "Manage private nameservers",
    "description": "Register, modify or delete private nameservers (glue records) of the domain; choose the operation with `action`:\n\n- `registerNameServer`: register a new glue record (needs `nameserver`, `ip`)\n- `modifyNameServer`: change the IP of a glue record (needs `nameserver`, `oldip`, `newip`)\n- `deleteNameServer`: delete a glue record (needs `nameserver`)",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-domain-id-reg"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "action": {
          "type": "string",
          "description": "Operation: registerNameServer, modifyNameServer, deleteNameServer"
         },
         "nameserver": {
          "type": "string",
          "description": "Full nameserver hostname"
         },
         "ip": {
          "type": "string",
          "description": "IP address for the nameserver – required for registerNameServer"
         },
         "oldip": {
          "type": "string",
          "description": "Current IP address – required for modifyNameServer"
         },
         "newip": {
          "type": "string",
          "description": "New IP address – required for modifyNameServer"
         }
        },
        "required": []
       },
       "example": {
        "action": "registerNameServer",
        "nameserver": "ns1.example.com",
        "ip": "203.0.113.10",
        "oldip": "203.0.113.10",
        "newip": "203.0.113.11"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "info": [
          "0 of 1 events processed",
          "actionsuccess"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/reglock": {
   "get": {
    "operationId": "get_domain_id_reglock",
    "summary": "Get domain lock",
    "description": "The domain's transfer lock (registrar lock) status.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-reglock"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "registrar_lock": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_domain_id_reglock",
    "summary": "Turn domain lock on or off",
    "description": "Turn the domain's transfer lock (registrar lock) on or off.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-reglock"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "switch": {
          "type": "boolean",
          "description": "true|false"
         }
        },
        "required": []
       },
       "example": {
        "switch": "true|false"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "info": [
          "success_changes_save"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/renew": {
   "post": {
    "operationId": "post_domain_id_renew",
    "summary": "Renew domain",
    "description": "Create a domain renewal order; returns the order number, invoice and total amount.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-domain-id-renew"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "years": {
          "type": "string",
          "description": "Number of years"
         },
         "pay_method": {
          "type": "integer",
          "description": "Payment method ID"
         }
        },
        "required": []
       },
       "example": {
        "years": "<years>",
        "pay_method": "<pay_method>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "order_num": 626303876,
         "invoice_id": "1201939",
         "total": "588109",
         "items": [
          {
           "type": "Domain Renew",
           "id": "200001",
           "name": "example.com",
           "product_id": "1435"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/sync": {
   "get": {
    "operationId": "get_domain_id_sync",
    "summary": "Sync domain",
    "description": "Sync the domain's status and expiry with the registrar.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-sync"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/lookup": {
   "post": {
    "operationId": "post_domain_lookup",
    "summary": "Check domain availability",
    "description": "Check whether a domain can be registered, with registration, transfer and renewal prices per number of years. `status: \"ok\"` when it is available.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-domain-lookup"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Domain name, ie. example.com"
         }
        },
        "required": []
       },
       "example": {
        "name": "<name>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "domain": "example.com",
         "name": "example.com",
         "sld": "example",
         "tld": ".com",
         "description": "",
         "premium": false,
         "avaliable": true,
         "transfer": false,
         "status": "ok",
         "type": "register",
         "category_id": "58",
         "tld_id": "346",
         "periods": [
          {
           "id": "346",
           "period": "1",
           "register": "319000.00",
           "transfer": "399000.00",
           "renew": "399000.00",
           "redemption": "3990000.00",
           "before": "399000.00",
           "vatFee": 29000,
           "feeRegOrigin": 290000
          },
          {
           "id": "346",
           "period": "2",
           "register": "638000.00",
           "transfer": "798000.00",
           "renew": "798000.00",
           "redemption": "7980000.00",
           "before": "-1.00",
           "vatFee": 58000,
           "feeRegOrigin": 580000
          },
          "… 8 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/name/{name}": {
   "get": {
    "operationId": "get_domain_name_name",
    "summary": "Domain details by name",
    "description": "Domain details by name (for example `example.com`) instead of ID.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-name-name"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "name",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain name"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domains": [
          {
           "id": "200001",
           "name": "example.com",
           "date_created": "2025-12-07",
           "firstpayment": "50000.00",
           "recurring_amount": "585366.00",
           "period": "1",
           "expires": "2026-12-07",
           "status": "Active",
           "next_due": "2026-12-07",
           "next_invoice": "2026-11-22",
           "idprotection": "1",
           "nameservers": [
            "ns1.tino.vn",
            "ns2.tino.vn"
           ],
           "autorenew": "1"
          }
         ],
         "page": {
          "current": 0,
          "total": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/order": {
   "get": {
    "operationId": "get_domain_order",
    "summary": "Available domain extensions",
    "description": "Domain extensions that can be registered or transferred in.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-order"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_domain_order",
    "summary": "Order domain",
    "description": "Create a standalone domain registration or transfer order. Check that the domain is available first (`POST /v1/domain/lookup`), otherwise the order may be cancelled.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-domain-order"
    },
    "security": [
     {
      "oauth": [
       "domains:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Domain name"
         },
         "years": {
          "type": "string",
          "description": "Number of years"
         },
         "action": {
          "type": "string",
          "description": "register|transfer"
         },
         "tld_id": {
          "type": "string",
          "description": "TLD id"
         },
         "pay_method": {
          "type": "integer",
          "description": "Payment method ID"
         },
         "epp": {
          "type": "string",
          "description": "EPP Transfer code, required when transfering some domains"
         },
         "nameservers": {
          "type": "array",
          "description": "Optional array with 2 - 4 nameservers that you want to use"
         },
         "registrant": {
          "type": "integer",
          "description": "Optional contact ID to use for registrant contact this domain"
         },
         "admin": {
          "type": "integer",
          "description": "Optional contact ID to use for admin contact this domain"
         },
         "tech": {
          "type": "integer",
          "description": "Optional contact ID to use for tech contact this domain"
         },
         "billing": {
          "type": "integer",
          "description": "Optional contact ID to use for billing contact this domain"
         },
         "data": {
          "type": "array",
          "description": "Addditional data required for some TLDs"
         },
         "aff_id": {
          "type": "integer",
          "description": "Affiliate ID"
         }
        },
        "required": []
       },
       "example": {
        "name": "example.com",
        "years": "<years>",
        "action": "<action>",
        "tld_id": "<tld_id>",
        "pay_method": "<pay_method>",
        "epp": "<epp>",
        "nameservers": "<nameservers>",
        "registrant": "<registrant>",
        "admin": "<admin>",
        "tech": "<tech>",
        "billing": "<billing>",
        "data": "<data>",
        "aff_id": 55
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/order/{id}/form": {
   "get": {
    "operationId": "get_domain_order_id_form",
    "summary": "Extra fields per domain extension",
    "description": "Extra fields that some domain extensions require when ordering. `@id` is the product ID of the domain extension (for example 1298 for `.io.vn`), not the ID of a registered domain.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-order-id-form"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Product ID of the domain extension (TLD)"
      }
     },
     {
      "name": "Name",
      "in": "In",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Description"
      }
     },
     {
      "name": "---",
      "in": "---",
      "required": false,
      "schema": {
       "type": "string",
       "description": "---"
      }
     },
     {
      "name": "tld_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "TLD ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "forms": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domains": {
   "get": {
    "operationId": "get_domains",
    "summary": "List domains (paginated)",
    "description": "The account's domains, paginated with `page` (starting at 0) and `perpage`.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domains"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domains": [
          {
           "id": "200001",
           "name": "example.com",
           "expires": "2026-12-07",
           "label": "",
           "recurring_amount": "585366.00",
           "date_created": "2025-12-07",
           "status": "Active",
           "period": "1",
           "idprotection": "1",
           "autorenew": "1",
           "daytoexpire": "127"
          }
         ],
         "total": 1,
         "page": {
          "current": 0,
          "total": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domains/{id}/registrant": {
   "get": {
    "operationId": "get_domains_id_registrant",
    "summary": "Read a waiting domain's registrant",
    "description": "Registrant (and household owner), eKYC and declaration status, and what is left to do for one domain awaiting registration. Requires the `domains:registrant` scope: only personal API tokens with an IP restriction. Response shape: [Domain registrant dossier](/en/docs/domain-registrant#reading-the-registrant).",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domains-id-registrant"
    },
    "security": [
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:registrant",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_domains_id_registrant",
    "summary": "Save a waiting domain's registrant",
    "description": "JSON body `{\"registrant\": {…}, \"owner\": {…} | null}` or `{\"from_domain_id\": N}` (the registrant of running domain N, from GET /v1/registrants). After saving, Tino tries to register right away and returns the new dossier. Requires the `domains:registrant` scope: only personal API tokens with an IP restriction. Required fields: [Domain registrant dossier](/en/docs/domain-registrant#saving-the-registrant).",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domains-id-registrant"
    },
    "security": [
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:registrant",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domains/pending": {
   "get": {
    "operationId": "get_domains_pending",
    "summary": "Domains awaiting their dossier",
    "description": "Paid domains that could not be registered yet because the registrant details or dossier (eKYC, declaration) are incomplete, with what is left to do (`actions`) and `ready` while Tino registers them. Requires the `domains:registrant` scope: only personal API tokens with an IP restriction. Guide: [Domain registrant dossier](/en/docs/domain-registrant).",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domains-pending"
    },
    "security": [
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:registrant",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/registrants": {
   "get": {
    "operationId": "get_registrants",
    "summary": "Registrants used before",
    "description": "Registrants of the customer's running domains, newest first, one row per person / organisation, to reuse for a waiting domain (`from_domain_id`). `ready: true` means the domain can be registered right away. Requires the `domains:registrant` scope: only personal API tokens with an IP restriction.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-registrants"
    },
    "security": [
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:registrant",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/whois/{domain}": {
   "get": {
    "operationId": "get_v1_whois_domain",
    "summary": "Domain whois lookup (with a token)",
    "description": "Same result as the [public route](/en/docs/api/get-whois-domain) `GET https://api.tino.vn/whois/<domain>`, called through the `/v1` gateway with a token that has `domains:read`: software that already holds a token keeps one base address, and lookups are logged per account.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-v1-whois-domain"
    },
    "security": [
     {
      "oauth": [
       "domains:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "domains:read",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain to look up (e.g. `example.com`), or an extension (e.g. `vn`)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domain": "example.com",
         "available": false,
         "status": "",
         "whois": {
          "domain": "example.com",
          "registrar": "Web Commerce Communications Ltd.",
          "createDate": "2025-12-07T11:00:00.471Z",
          "expiredDate": "2026-12-07T11:00:00.471Z",
          "updatedDate": "2026-03-30T16:00:00.697Z",
          "nameservers": [
           "ns1.tino.vn",
           "ns2.tino.vn"
          ],
          "status": [
           "clientDeleteProhibited https://example.org/epp#clientDeleteProhibited",
           "clientUpdateProhibited https://example.org/epp#clientUpdateProhibited",
           "… 1 more item(s)"
          ],
          "WhoisServer": "whois.webnic.cc"
         },
         "raw": "Domain Name: example.com<br />Registry Domain ID: DO_d59b4fbe41112c70f4c72e6116f376a3-ARUBA<br />Registrar WHOIS Server: whois.webnic.cc<br />Registrar URL: https://www.webnic.cc<br />Updated Date: 2026-03-30T16:00:00.697Z<br />Creation Date: 2025-12-07T11:00:00.471Z<br />Registry Expiry D…"
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/dns": {
   "get": {
    "operationId": "get_dns",
    "summary": "List DNS zones",
    "description": "All DNS zones of the account, with the DNS services that contain them.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-dns"
    },
    "security": [
     {
      "oauth": [
       "dns:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "service_ids": [
          "100003"
         ],
         "zones": [
          {
           "domain_id": "500001",
           "name": "example.com",
           "service_id": "100003"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/dns/templates": {
   "get": {
    "operationId": "get_dns_templates",
    "summary": "DNS record templates",
    "description": "Predefined DNS record templates (for example the default template, LadiPage).",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-dns-templates"
    },
    "security": [
     {
      "oauth": [
       "dns:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/dns": {
   "get": {
    "operationId": "get_domain_id_dns",
    "summary": "Domain DNS records",
    "description": "DNS records of the domain.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-dns"
    },
    "security": [
     {
      "oauth": [
       "dns:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_domain_id_dns",
    "summary": "Add DNS record to domain",
    "description": "Add a DNS record to the domain.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-domain-id-dns"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Reord name"
         },
         "type": {
          "type": "string",
          "description": "Reord type"
         },
         "priority": {
          "type": "string",
          "description": "Reord priority"
         },
         "content": {
          "type": "string",
          "description": "Reord content eg. IP addres for A records"
         }
        },
        "required": []
       },
       "example": {
        "name": "<name>",
        "type": "<type>",
        "priority": "<priority>",
        "content": "<content>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/dns/{index}": {
   "put": {
    "operationId": "put_domain_id_dns_index",
    "summary": "Edit domain DNS record",
    "description": "Edit DNS record number `@index` of the domain.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-domain-id-dns-index"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     },
     {
      "name": "index",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Position of the record in the domain's DNS record list"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "record_id": {
          "type": "integer",
          "description": "Recod index"
         },
         "name": {
          "type": "string",
          "description": "Record name"
         },
         "type": {
          "type": "string",
          "description": "Record type"
         },
         "priority": {
          "type": "string",
          "description": "Record priority"
         },
         "content": {
          "type": "string",
          "description": "Record content eg. IP address for A records"
         }
        },
        "required": []
       },
       "example": {
        "record_id": "<record_id>",
        "name": "<name>",
        "type": "<type>",
        "priority": "<priority>",
        "content": "<content>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "delete_domain_id_dns_index",
    "summary": "Delete domain DNS record",
    "description": "Delete DNS record number `@index` of the domain.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-domain-id-dns-index"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     },
     {
      "name": "index",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Position of the record in the domain's DNS record list"
      }
     },
     {
      "name": "record_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Recod index"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/domain/{id}/dns/types": {
   "get": {
    "operationId": "get_domain_id_dns_types",
    "summary": "Supported DNS record types",
    "description": "DNS record types available for the domain.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-domain-id-dns-types"
    },
    "security": [
     {
      "oauth": [
       "dns:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Domain ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{service_id}/dns": {
   "get": {
    "operationId": "get_service_service_id_dns",
    "summary": "DNS zones of a service",
    "description": "DNS zones in DNS service `@service_id`.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-service-id-dns"
    },
    "security": [
     {
      "oauth": [
       "dns:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:read",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "zones": [
          {
           "domain_id": "500001",
           "name": "example.com",
           "service_id": "100003"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_service_service_id_dns",
    "summary": "Add DNS zone",
    "description": "Create a new DNS zone in the DNS service.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-service-id-dns"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "DNS service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Zone name"
         }
        },
        "required": []
       },
       "example": {
        "name": "example.com"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{service_id}/dns/{zone_id}": {
   "get": {
    "operationId": "get_service_service_id_dns_zone_id",
    "summary": "DNS zone details",
    "description": "Details of the DNS zone and all its records.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-service-id-dns-zone-id"
    },
    "security": [
     {
      "oauth": [
       "dns:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:read",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS zone ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_service_service_id_dns_zone_id",
    "summary": "Edit DNS zone",
    "description": "Update the DNS zone's note.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-service-service-id-dns-zone-id"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS zone ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "comment": {
          "type": "string",
          "description": "Zone comment"
         }
        },
        "required": []
       },
       "example": {
        "comment": "<comment>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "delete_service_service_id_dns_zone_id",
    "summary": "Delete DNS zone",
    "description": "Delete the DNS zone.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-service-service-id-dns-zone-id"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS zone ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{service_id}/dns/{zone_id}/dnssec": {
   "get": {
    "operationId": "get_service_service_id_dns_zone_id_dnssec",
    "summary": "Get DNS zone DNSSEC",
    "description": "Whether DNSSEC is turned on for the DNS zone.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-service-id-dns-zone-id-dnssec"
    },
    "security": [
     {
      "oauth": [
       "dns:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:read",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS zone ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "dnssec": false
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_service_service_id_dns_zone_id_dnssec",
    "summary": "Turn DNS zone DNSSEC on or off",
    "description": "Turn DNSSEC on or off for the DNS zone; choose the operation with `widgetdo`.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-service-service-id-dns-zone-id-dnssec"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS zone ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "widgetdo": {
          "type": "string",
          "description": "widgetdo action"
         }
        },
        "required": [
         "widgetdo"
        ]
       },
       "example": {
        "widgetdo": "<widgetdo>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{service_id}/dns/{zone_id}/records": {
   "post": {
    "operationId": "post_service_service_id_dns_zone_id_records",
    "summary": "Add DNS record",
    "description": "Add a record to the DNS zone.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-service-id-dns-zone-id-records"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "DNS zone ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Record name"
         },
         "ttl": {
          "type": "integer",
          "description": "Record ttl"
         },
         "priority": {
          "type": "integer",
          "description": "Priority of the record"
         },
         "type": {
          "type": "string",
          "description": "Record type"
         },
         "content": {
          "type": "string",
          "description": "Contents of the record"
         }
        },
        "required": []
       },
       "example": {
        "name": "example.com",
        "ttl": 3600,
        "priority": 10,
        "type": "A",
        "content": "203.0.113.10"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "record": {
          "name": "tino-sdk-capture",
          "type": "TXT",
          "ttl": 3600,
          "priority": 0,
          "content": "<redacted>"
         },
         "info": [
          [
           "dnsnewrecordadded",
           "TXT"
          ]
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{service_id}/dns/{zone_id}/records/{record_id}": {
   "put": {
    "operationId": "put_service_service_id_dns_zone_id_records_record_id",
    "summary": "Edit DNS record",
    "description": "Edit a record of the DNS zone.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-service-service-id-dns-zone-id-records-record-id"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "DNS zone ID"
      }
     },
     {
      "name": "record_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "DNS record ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Record name"
         },
         "ttl": {
          "type": "integer",
          "description": "Record ttl"
         },
         "priority": {
          "type": "integer",
          "description": "Priority of the record"
         },
         "type": {
          "type": "string",
          "description": "Record type"
         },
         "content": {
          "type": "string",
          "description": "Contents of the record"
         }
        },
        "required": []
       },
       "example": {
        "name": "example.com",
        "ttl": 3600,
        "priority": 10,
        "type": "A",
        "content": "203.0.113.10"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "record": {
          "id": "419192",
          "type": "TXT",
          "ttl": 3600,
          "name": "tino-sdk-capture",
          "priority": 0,
          "content": "<redacted>"
         },
         "info": [
          "dnsrecordupdated"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "delete_service_service_id_dns_zone_id_records_record_id",
    "summary": "Delete DNS record",
    "description": "Delete a record of the DNS zone.",
    "tags": [
     "DNS"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-service-service-id-dns-zone-id-records-record-id"
    },
    "security": [
     {
      "oauth": [
       "dns:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "dns:write",
    "parameters": [
     {
      "name": "service_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS service ID"
      }
     },
     {
      "name": "zone_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS zone ID"
      }
     },
     {
      "name": "record_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "DNS record ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/addfunds": {
   "get": {
    "operationId": "get_addfunds",
    "summary": "Top-up information",
    "description": "Minimum and maximum top-up amounts and the payment gateways available.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-addfunds"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "min_amount": 50000,
         "max_amount": 500000000,
         "gateways": [
          {
           "id": 190,
           "name": "Thanh toán bằng chuyển khoản - QR Code - Momo - ZaloPay"
          },
          {
           "id": 70,
           "name": "Ví điện tử MoMo"
          },
          "… 2 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_addfunds",
    "summary": "Top up",
    "description": "Create a top-up invoice for the account; take `gateway` from `GET /v1/addfunds`.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-addfunds"
    },
    "security": [
     {
      "oauth": [
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "amount": {
          "type": "number",
          "description": "Amount to add to account"
         },
         "gateway": {
          "type": "number",
          "description": "Payment gateway ID, use `GET /addfunds` to list available gateways"
         }
        },
        "required": []
       },
       "example": {
        "amount": "100.00",
        "gateway": "<gateway>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "invoice_id": 1201937
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/balance": {
   "get": {
    "operationId": "get_balance",
    "summary": "Account balance",
    "description": "Total of unpaid invoices (`acc_balance`) and the credit balance (`acc_credit`).",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-balance"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "details": {
          "currency": "đ",
          "acc_balance": 574723,
          "acc_credit": "0.00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/billing/{invoice_id}/pay/{gateway_id}": {
   "get": {
    "operationId": "get_billing_invoice_id_pay_gateway_id",
    "summary": "Invoice payment link",
    "description": "Payment content for invoice `@invoice_id` through gateway `@gateway_id`.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-billing-invoice-id-pay-gateway-id"
    },
    "security": [
     {
      "oauth": [
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:write",
    "parameters": [
     {
      "name": "invoice_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Invoice ID"
      }
     },
     {
      "name": "gateway_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Payment gateway ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "content": "<redacted>"
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/billing/addfunds": {
   "post": {
    "operationId": "post_billing_addfunds",
    "summary": "Top up (billing)",
    "description": "Create a top-up invoice for the account.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-billing-addfunds"
    },
    "security": [
     {
      "oauth": [
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "funds": {
          "type": "integer",
          "description": "Amount of money"
         },
         "gateway": {
          "type": "integer",
          "description": "Payment Method"
         }
        },
        "required": []
       },
       "example": {
        "funds": 0,
        "gateway": 0
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "invoice_id": "1201937",
         "info": [
          "An invoice add credits have created"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/billing/creditlogs": {
   "get": {
    "operationId": "get_billing_creditlogs",
    "summary": "Credit balance history",
    "description": "Additions to and deductions from the account's credit balance.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-billing-creditlogs"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "logs": [],
         "page": {
          "total": 0,
          "pages": 0,
          "current": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/billing/creditvoucher": {
   "post": {
    "operationId": "post_billing_creditvoucher",
    "summary": "Redeem top-up code",
    "description": "Add credit with a voucher code.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-billing-creditvoucher"
    },
    "security": [
     {
      "oauth": [
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "code": {
          "type": "string",
          "description": "Voucher Code"
         }
        },
        "required": []
       },
       "example": {
        "code": "<code>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/estimate/{id}/pdf": {
   "get": {
    "operationId": "get_estimate_id_pdf",
    "summary": "Download estimate PDF",
    "description": "PDF file of estimate `@id`.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-estimate-id-pdf"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Estimate ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/estimates": {
   "get": {
    "operationId": "get_estimates",
    "summary": "List estimates",
    "description": "The account's estimates, paginated with `page` (starting at 0) and `perpage`.\n\nFilters: `filter[service_status]` by service status, `filter[service]` by service ID.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-estimates"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "estimates": [],
         "total": 0,
         "page": {
          "total": 0,
          "pages": 0,
          "current": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/estimates/{id}": {
   "get": {
    "operationId": "get_estimates_id",
    "summary": "Estimate details",
    "description": "Details of an estimate.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-estimates-id"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Estimate ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/invoice": {
   "get": {
    "operationId": "get_invoice",
    "summary": "List invoices",
    "description": "All invoices of the account.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-invoice"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "invoices": [
          {
           "id": "300001",
           "date": "2026-03-30",
           "dateorig": "2026-03-30",
           "duedate": "2026-12-07",
           "paybefore": "2026-12-07",
           "total": "574723.00",
           "subtotal": "532151.00",
           "tax": "42572.00",
           "tax2": "0.00",
           "datepaid": "0000-00-00 10:00:00",
           "status": "Unpaid",
           "merge_id": null,
           "number": "TNG300001",
           "currency": "VND"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/invoice/{id}": {
   "get": {
    "operationId": "get_invoice_id",
    "summary": "Invoice details",
    "description": "Invoice details: line items, tax, status, transactions.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-invoice-id"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Invoice ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "invoice": {
          "id": "300001",
          "status": "Unpaid",
          "contact_id": "0",
          "date": "2026-03-30",
          "duedate": "2026-12-07",
          "paybefore": "2026-12-07",
          "datepaid": "0000-00-00 10:00:00",
          "subtotal": 532151,
          "credit": 0,
          "tax": 42572,
          "taxrate": 10,
          "tax2": 0,
          "taxrate2": 0,
          "taxexempt": "0",
          "total": 574723,
          "grandtotal": 574723,
          "payment_module": "190",
          "rate": 1,
          "rate2": 0,
          "rate3": 1,
          "…": "11 more key(s)"
         },
         "cancancelinvoice": false,
         "invoicebody": "",
         "transactions": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "delete_invoice_id",
    "summary": "Delete invoice",
    "description": "Delete invoice `@id`.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-invoice-id"
    },
    "security": [
     {
      "oauth": [
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Invoice ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "info": [
          "invs_deleted"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/invoice/{id}/credit": {
   "post": {
    "operationId": "post_invoice_id_credit",
    "summary": "Pay invoice with balance",
    "description": "Use the account's credit balance to pay the invoice.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-invoice-id-credit"
    },
    "security": [
     {
      "oauth": [
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Invoice ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "amount": {
          "type": "string"
         }
        },
        "required": []
       },
       "example": {
        "amount": "short"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/invoice/{id}/pdf": {
   "get": {
    "operationId": "get_invoice_id_pdf",
    "summary": "Download invoice PDF",
    "description": "PDF file of the invoice, as a base64 string.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-invoice-id-pdf"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Invoice ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "invoice": "JVBERi0xLjQK…"
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/invoices": {
   "get": {
    "operationId": "get_invoices",
    "summary": "List invoices (paginated)",
    "description": "The account's invoices, paginated with `page` (starting at 0) and `perpage`.\n\nFilters: `filter[service_status]` by service status, `filter[service]` by service ID.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-invoices"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "invoices": [
          {
           "id": "300001",
           "date": "2026-03-30",
           "dateorig": "2026-03-30",
           "duedate": "2026-12-07",
           "paybefore": "2026-12-07",
           "total": "574723.00",
           "subtotal": "532151.00",
           "tax": "42572.00",
           "tax2": "0.00",
           "datepaid": "0000-00-00 10:00:00",
           "status": "Unpaid",
           "merge_id": null,
           "number": "TNG300001",
           "currency": "VND"
          }
         ],
         "total": 1,
         "page": {
          "total": 1,
          "pages": 1,
          "current": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/invoices/due": {
   "get": {
    "operationId": "get_invoices_due",
    "summary": "Due invoices",
    "description": "Unpaid invoices, paginated with `page` (starting at 0) and `perpage`.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-invoices-due"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "invoices_due": [
          {
           "id": "300001",
           "date": "2026-03-30",
           "duedate": "2026-12-07",
           "paybefore": "2026-12-07",
           "total": "574723.00",
           "status": "Unpaid",
           "number": "TNG300001",
           "currency": "VND"
          }
         ],
         "total": 1,
         "page": {
          "total": 1,
          "pages": 1,
          "current": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/invoices/payall": {
   "post": {
    "operationId": "post_invoices_payall",
    "summary": "Pay invoices together",
    "description": "Pay the invoices chosen in `selected` together; returns the `invoice_id` of the invoice to pay.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-invoices-payall"
    },
    "security": [
     {
      "oauth": [
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "selected": {
          "type": "array",
          "description": "selected invoice id"
         }
        },
        "required": []
       },
       "example": {
        "selected": []
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "invoice_id": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/payment": {
   "get": {
    "operationId": "get_payment",
    "summary": "Payment methods",
    "description": "Available payment methods.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-payment"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "payments": {
          "43": "VCB - Ngân hàng TMCP Ngoại Thương Việt Nam",
          "70": "Ví điện tử MoMo",
          "71": "Thanh toán Thẻ tín dụng - ATM",
          "190": "Thanh toán bằng chuyển khoản - QR Code - Momo - ZaloPay"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/payment/fees": {
   "get": {
    "operationId": "get_payment_fees",
    "summary": "Payment method fees",
    "description": "Payment methods with their fixed and percentage fees.",
    "tags": [
     "Invoices & payments"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-payment-fees"
    },
    "security": [
     {
      "oauth": [
       "billing:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "billing:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "payments": [
          {
           "id": 190,
           "name": "Thanh toán bằng chuyển khoản - QR Code - Momo - ZaloPay",
           "fixed_fee": "0",
           "percent_fee": "0",
           "icon": "payment-logo-190"
          },
          {
           "id": 70,
           "name": "Ví điện tử MoMo",
           "fixed_fee": "0",
           "percent_fee": "0",
           "icon": "payment-logo-70"
          },
          "… 2 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/carts": {
   "post": {
    "operationId": "post_carts",
    "summary": "Create a cart",
    "description": "Create a cart for the account (the token ties the cart to the account), optionally with `items`, `vat_info`, `aff_id`. Returns the cart `uuid`.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-carts"
    },
    "security": [
     {
      "oauth": [
       "orders:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "items": {
          "type": "array",
          "description": "Món theo định dạng POST /quote (product; domain đăng ký/chuyển)"
         }
        },
        "required": []
       },
       "example": {
        "items": "<items>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/carts/{uuid}": {
   "get": {
    "operationId": "get_carts_uuid",
    "summary": "Get a cart",
    "description": "The cart with prices computed at call time; the owner also sees the balance, `amount_due`, the transfer reference `pay_code` and `ready`.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-carts-uuid"
    },
    "security": [
     {
      "oauth": [
       "orders:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [
     {
      "name": "uuid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Cart code (`uuid` returned by POST /carts)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_carts_uuid",
    "summary": "Update a cart",
    "description": "Replace `items`, `vat_info`, `aff_id` and/or `current_step` (`cart`, `account`, `payment`). Send the full item list.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-carts-uuid"
    },
    "security": [
     {
      "oauth": [
       "orders:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [
     {
      "name": "uuid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Cart code (`uuid` returned by POST /carts)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/carts/{uuid}/confirm": {
   "post": {
    "operationId": "post_carts_uuid_confirm",
    "summary": "Place the order from a cart",
    "description": "With enough money (balance, or a bank transfer carrying `pay_code`) and complete details, creates the order and a paid invoice. Calling it again never creates a second order. Requires both `orders:write` and `billing:write`: missing either returns 403 `insufficient_scope`.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-carts-uuid-confirm"
    },
    "security": [
     {
      "oauth": [
       "orders:write",
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [
     {
      "name": "uuid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Cart code (`uuid` returned by POST /carts)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/carts/latest": {
   "get": {
    "operationId": "get_carts_latest",
    "summary": "Latest cart",
    "description": "The account's most recently edited cart that has no order yet.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-carts-latest"
    },
    "security": [
     {
      "oauth": [
       "orders:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/order": {
   "post": {
    "operationId": "post_order",
    "summary": "Order several services",
    "description": "Create an order and invoice for several items at once (service plans, domains, certificates), paid with `pay_method`. Per-item errors come back as HTTP 200 with `error` = `[\"item_error\", {code, message, item}]` (`item`: position in `items`); hosting plans need a `domain`. Requires both `orders:write` and `billing:write`: missing either returns 403 `insufficient_scope`.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-order"
    },
    "security": [
     {
      "oauth": [
       "orders:write",
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "pay_method": {
          "type": "integer",
          "description": "Payment method ID"
         },
         "ignore_errors": {
          "type": "boolean",
          "description": "Process order even if some of the items were rejected due to errors"
         },
         "items": {
          "type": "array",
          "description": "list with order items"
         },
         "aff_id": {
          "type": "integer",
          "description": "Affiliate ID"
         }
        },
        "required": []
       },
       "example": {
        "pay_method": 1,
        "ignore_errors": "No error",
        "items": [
         {
          "type": "certificate",
          "product_id": 840,
          "csr": "-----BEGIN CERTIFICATE REQUEST----- (...)",
          "years": 1,
          "approver_email": "admin@example.com"
         }
        ],
        "aff_id": 55
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/order/{product_id}": {
   "post": {
    "operationId": "post_order_product_id",
    "summary": "Order one service",
    "description": "Create an order for one plan by `product_id`, `cycle`, `domain` (legacy form; prefer POST /v1/order). Requires both `orders:write` and `billing:write`: missing either returns 403 `insufficient_scope`.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-order-product-id"
    },
    "security": [
     {
      "oauth": [
       "orders:write",
       "billing:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [
     {
      "name": "product_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Product ID (service plan, certificate)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "domain": {
          "type": "string",
          "description": "Domain name, ie. example.com, may be optional"
         },
         "cycle": {
          "type": "string",
          "description": "Billing period symbol"
         },
         "pay_method": {
          "type": "integer",
          "description": "Payment method ID"
         },
         "custom": {
          "type": "array",
          "description": "Additional options data available for sop products"
         },
         "promocode": {
          "type": "string",
          "description": "Promotion code"
         },
         "aff_id": {
          "type": "integer",
          "description": "Affiliate ID"
         }
        },
        "required": []
       },
       "example": {
        "domain": "<domain>",
        "cycle": "<cycle>",
        "pay_method": "<pay_method>",
        "custom": "<custom>",
        "promocode": "<promocode>",
        "aff_id": 55
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/quote": {
   "post": {
    "operationId": "post_quote",
    "summary": "Get an order quote",
    "description": "Price a list of items (service plans, domains) as they would be ordered: subtotal, tax, discounts, renewal prices. Creates no order and no invoice. Same `items` shape as POST /v1/order.",
    "tags": [
     "Orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-quote"
    },
    "security": [
     {
      "oauth": [
       "orders:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "orders:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "pay_method": {
          "type": "integer",
          "description": "Payment method ID"
         },
         "output": {
          "type": "string",
          "description": "Type of output, default is short. Possible options    short - Basic details about the item in cart</li>  config- Basic details and form components</li>  full - All details available in cart</li> </ul>"
         },
         "items": {
          "type": "array",
          "description": "list with order items"
         }
        },
        "required": []
       },
       "example": {
        "pay_method": "<pay_method>",
        "output": "short",
        "items": [
         {
          "type": "certificate",
          "product_id": 840,
          "csr": "-----BEGIN CERTIFICATE REQUEST----- (...)",
          "years": 1,
          "approver_email": "admin@example.com"
         }
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "summary": {
          "subtotal": 79000,
          "total": 85320,
          "setup_fee": 0,
          "credit": 0,
          "discount": 0,
          "cost": 79000,
          "recurring": [
           {
            "title": "1 tháng",
            "price": 85320,
            "value": "m"
           }
          ],
          "recurring_discount": [],
          "tax": [
           {
            "name": "VAT",
            "tax": 6320,
            "value": 8
           }
          ]
         },
         "items": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/knowledgebase": {
   "get": {
    "operationId": "get_knowledgebase",
    "summary": "Knowledge base categories",
    "description": "All categories of the knowledge base.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-knowledgebase"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "categories": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/knowledgebase/{category_id}": {
   "get": {
    "operationId": "get_knowledgebase_category_id",
    "summary": "Articles in a category",
    "description": "Subcategories and articles of a knowledge base category.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-knowledgebase-category-id"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [
     {
      "name": "category_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Knowledgebase category ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "subcategories": null,
         "articles": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/knowledgebase/article/{article_id}": {
   "get": {
    "operationId": "get_knowledgebase_article_article_id",
    "summary": "Knowledge base article",
    "description": "Content of a knowledge base article.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-knowledgebase-article-article-id"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [
     {
      "name": "article_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Knowledgebase article ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "article": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/news": {
   "get": {
    "operationId": "get_news",
    "summary": "List news",
    "description": "Tino news and announcements.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-news"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "news": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/news/{news_id}": {
   "get": {
    "operationId": "get_news_news_id",
    "summary": "News details",
    "description": "Content of a news item.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-news-news-id"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [
     {
      "name": "news_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "News item ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "annoucement": null
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/ticket/attachment/{file}": {
   "get": {
    "operationId": "get_ticket_attachment_file",
    "summary": "Download ticket attachment",
    "description": "A ticket's attached file.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-ticket-attachment-file"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [
     {
      "name": "file",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Ticket attachment file code"
      }
     },
     {
      "name": "Name",
      "in": "In",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Description"
      }
     },
     {
      "name": "---",
      "in": "---",
      "required": false,
      "schema": {
       "type": "string",
       "description": "---"
      }
     },
     {
      "name": "number",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Ticket number"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": [
         "file_not_found"
        ]
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/ticket/departments": {
   "get": {
    "operationId": "get_ticket_departments",
    "summary": "Support departments",
    "description": "Departments that receive tickets (`id` is used as `dept_id` when creating a ticket).",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-ticket-departments"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "departments": [
          {
           "id": "2",
           "name": "Phòng hỗ trợ kỹ thuật",
           "description": "Nơi tiếp nhận những yêu cầu hỗ trợ kỹ thuật. Khách hàng có thể liên hệ trực tiếp qua hotline 0364.333.333 nhấn phím 2 hoặc email user@example.com trong trường hợp khẩn cấp.",
           "allow_priority": true
          },
          {
           "id": "3",
           "name": "Phòng Kinh Doanh",
           "description": "Nơi tiếp nhận và giải quyết những vấn đề liên quan đến báo giá, hợp đồng và dịch vụ. Khách hàng có thể liên hệ trực tiếp hotline 0364.333.333 nhấn phím 1 hoặc email user@example.com trong trường hợp khẩn cấp.",
           "allow_priority": false
          },
          "… 5 more item(s)"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/tickets": {
   "get": {
    "operationId": "get_tickets",
    "summary": "List tickets",
    "description": "The account's support tickets.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-tickets"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Zero-based page index. page=0 is the first page; the response echoes it 1-based in page.current. Default: `0`."
      }
     },
     {
      "name": "perpage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Rows per page. Defaults to the account's RecordsPerPage setting."
      }
     },
     {
      "name": "orderby",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Sort expression in the form `field|DESC` or `field|ASC`, e.g. `date|DESC`."
      }
     },
     {
      "name": "filter",
      "in": "query",
      "required": false,
      "schema": {
       "type": "object",
       "description": "Endpoint-specific filters, serialised as filter[key]=value."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "tickets": [
          {
           "client_read": "1",
           "ticket_number": "400001",
           "date": "2026-07-24 10:00:00",
           "deptname": "Phòng hỗ trợ kỹ thuật",
           "subject": "test example.org",
           "status": "Closed",
           "lastreply": "2026-07-24 10:00:00"
          },
          {
           "client_read": "1",
           "ticket_number": "400002",
           "date": "2026-07-24 10:00:00",
           "deptname": "Phòng quản lý tên miền",
           "subject": "test email",
           "status": "Answered",
           "lastreply": "2026-07-24 10:00:00"
          },
          "… 5 more item(s)"
         ],
         "page": {
          "current": 0,
          "total": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_tickets",
    "summary": "Create ticket",
    "description": "Create a new support ticket. Returns the ticket number in the `ticket` field (not `ticket_number`), for example `{\"ticket\": 886174}`; use this number as `@number` in the other ticket routes.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-tickets"
    },
    "security": [
     {
      "oauth": [
       "tickets:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:write",
    "parameters": [],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "dept_id": {
          "type": "integer",
          "description": "Department id"
         },
         "subject": {
          "type": "string",
          "description": "Ticket subject"
         },
         "body": {
          "type": "string",
          "description": "Ticket message"
         }
        },
        "required": []
       },
       "example": {
        "dept_id": 1,
        "subject": "Subject",
        "body": "Message ..."
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "ticket": 886174
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/tickets/{number}": {
   "get": {
    "operationId": "get_tickets_number",
    "summary": "Ticket details",
    "description": "Ticket content and all replies.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-tickets-number"
    },
    "security": [
     {
      "oauth": [
       "tickets:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:read",
    "parameters": [
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Ticket number"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "ticket": {
          "date": "2026-07-24 10:00:00",
          "ticket_number": "400001",
          "name": "Nguyen Van A",
          "email": "user@example.com",
          "subject": "test example.org",
          "body": "Nơi tiếp nhận những yêu cầu hỗ trợ bản khai, xác thực tên miền. Khách hàng có thể liên hệ trực tiếp qua hotline 0364.333.333 nhấn phím 2",
          "status": "Closed",
          "client_read": "1",
          "type": "Email",
          "deptname": "Phòng hỗ trợ kỹ thuật",
          "attachments": []
         },
         "replies": []
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_tickets_number",
    "summary": "Reply to ticket",
    "description": "Send a reply to the ticket.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-tickets-number"
    },
    "security": [
     {
      "oauth": [
       "tickets:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:write",
    "parameters": [
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Ticket number"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "body": {
          "type": "string",
          "description": "Reply message"
         }
        },
        "required": []
       },
       "example": {
        "body": "reply text .."
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "info": [
          "reply_added"
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/tickets/{number}/close": {
   "put": {
    "operationId": "put_tickets_number_close",
    "summary": "Close ticket",
    "description": "Close the ticket.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-tickets-number-close"
    },
    "security": [
     {
      "oauth": [
       "tickets:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:write",
    "parameters": [
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Ticket number"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "status": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/tickets/{number}/open": {
   "put": {
    "operationId": "put_tickets_number_open",
    "summary": "Reopen ticket",
    "description": "Reopen a closed ticket.",
    "tags": [
     "Tickets & support"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-tickets-number-open"
    },
    "security": [
     {
      "oauth": [
       "tickets:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "tickets:write",
    "parameters": [
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Ticket number"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "status": true
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/events": {
   "get": {
    "operationId": "get_service_id_waf_events",
    "summary": "Event summary",
    "description": "Total, blocked and challenged per day and the top 5 reasons. Query `days` (default 7).",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-events"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "days",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Number of days to summarise. Default: `7`."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/ip-rules": {
   "get": {
    "operationId": "get_service_id_waf_ip_rules",
    "summary": "List IP rules",
    "description": "IP block/allow list of the account, applied to every website. Query: `action`, `page`, `per_page`.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-ip-rules"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "action",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Only entries with this action: `block` or `allow`."
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Page number, from 1."
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Items per page."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_service_id_waf_ip_rules",
    "summary": "Block or allow an IP",
    "description": "Body `value` (IP or range), `action` (block or allow), `note` (optional). Returns HTTP 200 instead of 201 when the entry already exists.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-waf-ip-rules"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "value": {
          "type": "string",
          "description": "IP address or range (CIDR), e.g. `203.0.113.10` or `203.0.113.0/24`."
         },
         "action": {
          "type": "string",
          "description": "`block` or `allow`."
         },
         "note": {
          "type": "string",
          "description": "Note shown in the list."
         }
        },
        "required": [
         "value",
         "action"
        ]
       },
       "example": {
        "value": "203.0.113.0/24",
        "action": "block",
        "note": "Quét cổng"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/ip-rules/{rule}": {
   "delete": {
    "operationId": "delete_service_id_waf_ip_rules_rule",
    "summary": "Delete an IP rule",
    "description": "Deletes one block/allow entry by ID (UUID).",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-service-id-waf-ip-rules-rule"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "rule",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "ID (UUID) of the IP block/allow entry"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/ip-rules/apply": {
   "post": {
    "operationId": "post_service_id_waf_ip_rules_apply",
    "summary": "Re-apply IP rules",
    "description": "Puts the IP rules back on every website missing them; returns `not_enforced`.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-waf-ip-rules-apply"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/overview": {
   "get": {
    "operationId": "get_service_id_waf_overview",
    "summary": "TinoWAF overview",
    "description": "Service status, effective limits, usage and the link that opens TinoWAF.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-overview"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones": {
   "get": {
    "operationId": "get_service_id_waf_zones",
    "summary": "List websites",
    "description": "Websites protected by TinoWAF. Query: `page`, `per_page`.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-zones"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Page number, from 1."
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Items per page."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_service_id_waf_zones",
    "summary": "Add a website",
    "description": "Adds a website, all or nothing: body `apex` (main domain), `hostnames` (subdomains, optional), `origins` (origin servers). Returns the website, its domain names, the DNS records to set, the origin and warnings.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-waf-zones"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "apex": {
          "type": "string",
          "description": "Main domain of the website, e.g. `example.com`."
         },
         "hostnames": {
          "type": "array",
          "description": "Subdomains to protect as well, e.g. `[\"www.example.com\"]`."
         },
         "origins": {
          "type": "array",
          "description": "Origin servers: `[{address, port, tls_mode}]`, `address` an IP or host name; `tls_mode` is `verify` (HTTPS, certificate checked), `no_verify` (HTTPS, self-signed certificate) or `plain` (HTTP), among `tls_modes` of the origin route."
         }
        },
        "required": [
         "apex",
         "origins"
        ]
       },
       "example": {
        "apex": "example.com",
        "hostnames": [
         "www.example.com"
        ],
        "origins": [
         {
          "address": "203.0.113.10",
          "port": 443,
          "tls_mode": "verify"
         }
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}": {
   "get": {
    "operationId": "get_service_id_waf_zones_zone",
    "summary": "Get a website",
    "description": "One website by ID (UUID).",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-zones-zone"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "delete_service_id_waf_zones_zone",
    "summary": "Delete a website",
    "description": "TinoWAF removes the website from protection at once; returns `{id, deleted: true}`.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-service-id-waf-zones-zone"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}/check": {
   "post": {
    "operationId": "post_service_id_waf_zones_zone_check",
    "summary": "Check DNS now",
    "description": "Verifies the domain names waiting for DNS and re-verifies the expired ones; returns the DNS setup, the website and the check result.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-waf-zones-zone-check"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}/events": {
   "get": {
    "operationId": "get_service_id_waf_zones_zone_events",
    "summary": "List a website's events",
    "description": "Newest events first. Query: `action`, `from`, `to` (RFC 3339), `cursor`, `limit`; `meta.next_cursor` gives the next page.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-zones-zone-events"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     },
     {
      "name": "action",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Only events with this action: `block`, `challenge`, `rate_limited` or `log`."
      }
     },
     {
      "name": "from",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Start time, RFC 3339 (e.g. `2026-10-27T00:00:00+07:00`)."
      }
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "End time, RFC 3339."
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`meta.next_cursor` of the previous page."
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Events per page."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}/hostnames": {
   "get": {
    "operationId": "get_service_id_waf_zones_zone_hostnames",
    "summary": "List a website's domain names",
    "description": "Domain names of the website with the DNS records to set and the domain name limit.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-zones-zone-hostnames"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "post_service_id_waf_zones_zone_hostnames",
    "summary": "Add a domain name to a website",
    "description": "Body `name`: the domain name to add. Returns the DNS records to set.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/post-service-id-waf-zones-zone-hostnames"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Domain name to add, e.g. `shop.example.com`."
         }
        },
        "required": [
         "name"
        ]
       },
       "example": {
        "name": "shop.example.com"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}/hostnames/{hostname}": {
   "delete": {
    "operationId": "delete_service_id_waf_zones_zone_hostnames_hostname",
    "summary": "Remove a domain name from a website",
    "description": "Removes a domain name by ID (UUID); returns the remaining DNS setup.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/delete-service-id-waf-zones-zone-hostnames-hostname"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     },
     {
      "name": "hostname",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain name ID (UUID) of the website"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}/origin": {
   "get": {
    "operationId": "get_service_id_waf_zones_zone_origin",
    "summary": "Get a website's origin servers",
    "description": "Origin servers, the available TLS modes and the limit.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-service-id-waf-zones-zone-origin"
    },
    "security": [
     {
      "oauth": [
       "waf:read"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:read",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "put_service_id_waf_zones_zone_origin",
    "summary": "Update origin servers",
    "description": "Replaces all origin servers: body `origins`, each `{address, port, tls_mode}`. Returns the same as the read route, plus warnings.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-service-id-waf-zones-zone-origin"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "origins": {
          "type": "array",
          "description": "The full list of origin servers, replacing the current one: `[{address, port, tls_mode}]`, as when adding the website."
         }
        },
        "required": [
         "origins"
        ]
       },
       "example": {
        "origins": [
         {
          "address": "203.0.113.10",
          "port": 443,
          "tls_mode": "verify"
         }
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}/under-attack": {
   "put": {
    "operationId": "put_service_id_waf_zones_zone_under_attack",
    "summary": "Turn emergency anti-attack mode on or off",
    "description": "Emergency anti-attack mode of the website: body `enabled` (`true` or `false`).",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-service-id-waf-zones-zone-under-attack"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "enabled": {
          "type": "boolean",
          "description": "`true` turns the emergency anti-attack mode on, `false` turns it off."
         }
        },
        "required": [
         "enabled"
        ]
       },
       "example": {
        "enabled": true
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/v1/service/{id}/waf/zones/{zone}/waf-mode": {
   "put": {
    "operationId": "put_service_id_waf_zones_zone_waf_mode",
    "summary": "Change the protection level",
    "description": "Body `mode`: `off`, `audit`, `balanced` or `strict`. Returns the website.",
    "tags": [
     "TinoWAF"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/put-service-id-waf-zones-zone-waf-mode"
    },
    "security": [
     {
      "oauth": [
       "waf:write"
      ]
     },
     {
      "personalToken": []
     }
    ],
    "x-tino-scope": "waf:write",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Service ID"
      }
     },
     {
      "name": "zone",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID) on TinoWAF"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "mode": {
          "type": "string",
          "description": "Protection level: `off`, `audit`, `balanced` or `strict`."
         }
        },
        "required": [
         "mode"
        ]
       },
       "example": {
        "mode": "balanced"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay": {
   "get": {
    "operationId": "tinopay_get_merchant",
    "summary": "Merchant details",
    "description": "The service's TinoPay merchant: merchant ID, name, email, phone, package (`package`: transaction limit, start and end dates; `end_at` is `null` when open-ended), payment codes (`pay_codes`), status (`status`, `suspended_at`), bank accounts (with `virtual_accounts_count`). Use this route to confirm a service is TinoPay: see [Getting started with TinoPay](/en/docs/tinopay-start#finding-the-tinopay-service).",
    "tags": [
     "Merchant"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-merchant"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "tino_sub": "700001",
          "account_id": 100001,
          "merchant_id": 8,
          "name": "Công ty TNHH ABC",
          "email": "billing@example.com",
          "phone": "0900000000",
          "status": "active",
          "pay_codes": [
           "DH"
          ],
          "suspended_at": null,
          "created_at": "2026-10-20T15:32:24+07:00",
          "package": {
           "id": 2,
           "name": "Pro 5000",
           "limit_transactions": 5000,
           "start_at": "2026-10-20",
           "end_at": null
          },
          "bank_accounts": [
           {
            "id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
            "bank_code": "BIDV",
            "account_no": "96240000001",
            "account_holder_name": "CONG TY ABC",
            "hint_name": "Quầy chính",
            "is_business": true,
            "first_va_number": "9624",
            "service_id": "AP0012",
            "status": "active",
            "provision_status": "active",
            "provision_note": null,
            "activated_at": "2026-10-20T10:00:00+07:00",
            "virtual_accounts_count": 3,
            "created_at": "2026-10-20T09:55:00+07:00"
           }
          ]
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "patch": {
    "operationId": "tinopay_patch_merchant",
    "summary": "Update merchant details",
    "description": "Send only the fields to change, as a JSON body (required for `PATCH`): `name`, `email`, `phone`, `pay_codes` (payment-code patterns extracted from transfer descriptions, array of strings up to 20 characters; `[]` removes all; the extracted code is the webhook's `code` field). Returns the updated merchant. Email already used by another Tino customer: 409 `EMAIL_TAKEN`; invalid data: 422 `VALIDATION_FAILED`. These details are not synced with the customer's Tino profile.",
    "tags": [
     "Merchant"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-patch-merchant"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "≤ 255"
         },
         "email": {
          "type": "string",
          "description": "≤ 255"
         },
         "phone": {
          "type": "string",
          "description": "≤ 20"
         },
         "pay_codes": {
          "type": "array",
          "description": "Cấu trúc mã thanh toán trích từ nội dung chuyển khoản, mảng chuỗi ≤ 20 ký tự; [] = bỏ hết"
         }
        },
        "required": []
       },
       "example": {
        "name": "Cửa hàng ABC",
        "pay_codes": [
         "DH"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "tino_sub": "700001",
          "account_id": 100001,
          "merchant_id": 8,
          "name": "Cửa hàng ABC",
          "email": "billing@example.com",
          "phone": "0900000000",
          "status": "active",
          "pay_codes": [
           "DH"
          ],
          "suspended_at": null,
          "created_at": "2026-10-20T15:32:24+07:00",
          "package": {
           "id": 2,
           "name": "Pro 5000",
           "limit_transactions": 5000,
           "start_at": "2026-10-20",
           "end_at": null
          },
          "bank_accounts": [
           {
            "id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
            "bank_code": "BIDV",
            "account_no": "96240000001",
            "account_holder_name": "CONG TY ABC",
            "hint_name": "Quầy chính",
            "is_business": true,
            "first_va_number": "9624",
            "service_id": "AP0012",
            "status": "active",
            "provision_status": "active",
            "provision_note": null,
            "activated_at": "2026-10-20T10:00:00+07:00",
            "virtual_accounts_count": 3,
            "created_at": "2026-10-20T09:55:00+07:00"
           }
          ]
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/pay-codes": {
   "get": {
    "operationId": "tinopay_get_pay_codes",
    "summary": "Payment code patterns",
    "description": "Patterns TinoPay uses to extract `code` from the transfer content (the webhook's `code` field), also the order code prefix of the Sapo integration. Returns `[{prefix, suffix_from, suffix_to, character_type}]`; e.g. `DH` + 6–8 digits: content `DH123456 thanh toan` gives the code `DH123456`.",
    "tags": [
     "Merchant"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-pay-codes"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "prefix": "DH",
           "suffix_from": 6,
           "suffix_to": 8,
           "character_type": "NumberOnly"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "tinopay_put_pay_codes",
    "summary": "Save payment code patterns",
    "description": "Replaces the whole list: body `{\"pay_codes\": [...]}` sends every existing pattern plus the new ones, `[]` removes all; at most 20 patterns. `prefix` 2–5 letters or digits (stored upper case, unique), `suffix_from` ≤ `suffix_to` within 1–30, `character_type` `NumberOnly` or `NumberAndLetter`. Returns the list after saving. Dropping a prefix a Sapo integration uses: 409 `RESOURCE_IN_USE`, `details.prefixes` lists those prefixes.",
    "tags": [
     "Merchant"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-put-pay-codes"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "pay_codes": {
          "type": "array"
         }
        },
        "required": [
         "pay_codes"
        ]
       },
       "example": {
        "pay_codes": [
         {
          "prefix": "DH",
          "suffix_from": 6,
          "suffix_to": 8,
          "character_type": "NumberOnly"
         },
         {
          "prefix": "TNG",
          "suffix_from": 1,
          "suffix_to": 12,
          "character_type": "NumberOnly"
         }
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "prefix": "DH",
           "suffix_from": 6,
           "suffix_to": 8,
           "character_type": "NumberOnly"
          },
          {
           "prefix": "TNG",
           "suffix_from": 1,
           "suffix_to": 12,
           "character_type": "NumberOnly"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/bank-accounts": {
   "get": {
    "operationId": "tinopay_get_bank_accounts",
    "summary": "List bank accounts",
    "description": "The merchant's linked bank accounts: bank, account number, holder, VA prefix (`first_va_number`), status, number of virtual accounts. Bank credentials are never returned.",
    "tags": [
     "Bank accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-bank-accounts"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
           "bank_code": "BIDV",
           "account_no": "96240000001",
           "account_holder_name": "CONG TY ABC",
           "hint_name": "Quầy chính",
           "is_business": true,
           "first_va_number": "9624",
           "service_id": "AP0012",
           "status": "active",
           "provision_status": "active",
           "provision_note": null,
           "activated_at": "2026-10-20T10:00:00+07:00",
           "virtual_accounts_count": 3,
           "created_at": "2026-10-20T09:55:00+07:00"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/bank-accounts/{bank}": {
   "get": {
    "operationId": "tinopay_get_bank_accounts_bank",
    "summary": "Bank account details",
    "description": "One linked bank account of the merchant.",
    "tags": [
     "Bank accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-bank-accounts-bank"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Bank account ID (`id` in the bank account list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "bank_code": "BIDV",
          "account_no": "96240000001",
          "account_holder_name": "CONG TY ABC",
          "hint_name": "Quầy chính",
          "is_business": true,
          "first_va_number": "9624",
          "service_id": "AP0012",
          "status": "active",
          "provision_status": "active",
          "provision_note": null,
          "activated_at": "2026-10-20T10:00:00+07:00",
          "virtual_accounts_count": 3,
          "created_at": "2026-10-20T09:55:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/bank-links/bidv-business": {
   "post": {
    "operationId": "tinopay_post_bank_links_bidv_business",
    "summary": "Request a BIDV business link",
    "description": "BIDV business accounts are not linked automatically: the route opens a request so staff set up the service with BIDV; the account then appears in the bank account list. Returns 201 `{ticket_id, status, created_at}`.",
    "tags": [
     "Bank accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-bank-links-bidv-business"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Người liên hệ"
         },
         "phone": {
          "type": "string"
         },
         "has_bidv_account": {
          "type": "boolean"
         },
         "note": {
          "type": "string"
         }
        },
        "required": []
       },
       "example": {
        "name": "Nguyễn Văn A",
        "phone": "0900000000",
        "has_bidv_account": true,
        "note": "Liên hệ buổi sáng"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "ticket_id": 41,
          "status": 1,
          "created_at": "2026-10-20T15:40:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/bank-accounts/{bank}/virtual-accounts": {
   "get": {
    "operationId": "tinopay_get_bank_accounts_bank_virtual_accounts",
    "summary": "List virtual accounts (VA)",
    "description": "Virtual accounts of one bank account, filtered by `q` (VA number, name) and `status`; paginated with `page`, `per_page` (up to 100).",
    "tags": [
     "Virtual accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-bank-accounts-bank-virtual-accounts"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Bank account ID (`id` in the bank account list)"
      }
     },
     {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Số VA, tên"
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "active | inactive"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "≤ 100"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 51,
           "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
           "account_number": "9624QA01",
           "account_name": "CUA HANG A",
           "status": "active",
           "created_at": "2026-10-20T10:05:00+07:00"
          }
         ],
         "meta": {
          "page": 1,
          "per_page": 20,
          "total": 1,
          "last_page": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "tinopay_post_bank_accounts_bank_virtual_accounts",
    "summary": "Create a virtual account",
    "description": "VA number = the bank account's `first_va_number` + `va_number` (suffix A–Z, 0–9, up to 7 characters; lowercase is upper-cased). `account_name`: A–Z, 0–9 and spaces, up to 50 characters, no diacritics. Duplicate number: 409 `VA_NUMBER_EXISTS`; bank account without a VA prefix: 422 `VALIDATION_FAILED`.",
    "tags": [
     "Virtual accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-bank-accounts-bank-virtual-accounts"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Bank account ID (`id` in the bank account list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "va_number": {
          "type": "string",
          "description": "Phần đuôi, A–Z 0–9, tối đa 7 ký tự"
         },
         "account_name": {
          "type": "string",
          "description": "A–Z 0–9 và khoảng trắng, tối đa 50 ký tự, không dấu"
         }
        },
        "required": [
         "va_number",
         "account_name"
        ]
       },
       "example": {
        "va_number": "QA01",
        "account_name": "CUA HANG A"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 51,
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "account_number": "9624QA01",
          "account_name": "CUA HANG A",
          "status": "active",
          "created_at": "2026-10-20T10:05:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/bank-accounts/{bank}/virtual-accounts/{va}/activate": {
   "post": {
    "operationId": "tinopay_post_bank_accounts_bank_virtual_accounts_va_activate",
    "summary": "Activate a virtual account",
    "description": "Re-open a deactivated virtual account; returns the virtual account after the change.",
    "tags": [
     "Virtual accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-bank-accounts-bank-virtual-accounts-va-activate"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Bank account ID (`id` in the bank account list)"
      }
     },
     {
      "name": "va",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Virtual account ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 51,
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "account_number": "9624QA01",
          "account_name": "CUA HANG A",
          "status": "active",
          "created_at": "2026-10-20T10:05:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/bank-accounts/{bank}/virtual-accounts/{va}/deactivate": {
   "post": {
    "operationId": "tinopay_post_bank_accounts_bank_virtual_accounts_va_deactivate",
    "summary": "Deactivate a virtual account",
    "description": "Deactivate a virtual account; returns the virtual account after the change.",
    "tags": [
     "Virtual accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-bank-accounts-bank-virtual-accounts-va-deactivate"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Bank account ID (`id` in the bank account list)"
      }
     },
     {
      "name": "va",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Virtual account ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 51,
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "account_number": "9624QA01",
          "account_name": "CUA HANG A",
          "status": "inactive",
          "created_at": "2026-10-20T10:05:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/bank-accounts/{bank}/virtual-accounts/{va}": {
   "delete": {
    "operationId": "tinopay_delete_bank_accounts_bank_virtual_accounts_va",
    "summary": "Delete a virtual account",
    "description": "Delete a virtual account; returns `{id, deleted: true}`.",
    "tags": [
     "Virtual accounts"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-delete-bank-accounts-bank-virtual-accounts-va"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Bank account ID (`id` in the bank account list)"
      }
     },
     {
      "name": "va",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Virtual account ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 51,
          "deleted": true
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/webhooks": {
   "get": {
    "operationId": "tinopay_get_webhooks",
    "summary": "List webhooks",
    "description": "The merchant's webhooks, filtered by `bank_account_id`. Each webhook has a `token` sent with every delivery (see [Receiving TinoPay webhooks](/en/docs/tinopay-webhook)).",
    "tags": [
     "Webhooks"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-webhooks"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank_account_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 12,
           "name": "Đơn hàng website",
           "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
           "url": "https://example.com/tinopay/hook",
           "token": "<token>",
           "event": "in",
           "skip_if_no_code": false,
           "virtual_accounts": [
            "9624QA01"
           ],
           "status": "active",
           "created_at": "2026-10-20T10:10:00+07:00",
           "updated_at": "2026-10-20T10:10:00+07:00"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "tinopay_post_webhooks",
    "summary": "Create a webhook",
    "description": "Create a webhook for one bank account: receiving `url`, `event` (`in` incoming, `out` outgoing, `all`), `virtual_accounts` (empty: every VA), `skip_if_no_code` (skip transactions without an extracted payment code). Leave `token` empty to get a generated 50-character token.",
    "tags": [
     "Webhooks"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-webhooks"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "≤ 250"
         },
         "bank_account_id": {
          "type": "string"
         },
         "url": {
          "type": "string",
          "description": "≤ 250"
         },
         "event": {
          "type": "string",
          "description": "in | out | all"
         },
         "token": {
          "type": "string"
         },
         "skip_if_no_code": {
          "type": "boolean"
         },
         "virtual_accounts": {
          "type": "array"
         },
         "status": {
          "type": "string",
          "description": "active | inactive"
         }
        },
        "required": [
         "name",
         "bank_account_id",
         "url",
         "event"
        ]
       },
       "example": {
        "name": "Đơn hàng website",
        "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
        "url": "https://example.com/tinopay/hook",
        "event": "in",
        "virtual_accounts": [
         "9624QA01"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 12,
          "name": "Đơn hàng website",
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "url": "https://example.com/tinopay/hook",
          "token": "<token>",
          "event": "in",
          "skip_if_no_code": false,
          "virtual_accounts": [
           "9624QA01"
          ],
          "status": "active",
          "created_at": "2026-10-20T10:10:00+07:00",
          "updated_at": "2026-10-20T10:10:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/webhooks/{webhook}": {
   "get": {
    "operationId": "tinopay_get_webhooks_webhook",
    "summary": "Webhook details",
    "description": "One webhook of the merchant.",
    "tags": [
     "Webhooks"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-webhooks-webhook"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "webhook",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Webhook ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 12,
          "name": "Đơn hàng website",
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "url": "https://example.com/tinopay/hook",
          "token": "<token>",
          "event": "in",
          "skip_if_no_code": false,
          "virtual_accounts": [
           "9624QA01"
          ],
          "status": "active",
          "created_at": "2026-10-20T10:10:00+07:00",
          "updated_at": "2026-10-20T10:10:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "patch": {
    "operationId": "tinopay_patch_webhooks_webhook",
    "summary": "Update a webhook",
    "description": "Send only the fields to change, as a JSON body. A new `bank_account_id` must also belong to the merchant.",
    "tags": [
     "Webhooks"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-patch-webhooks-webhook"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "webhook",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Webhook ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "bank_account_id": {
          "type": "string"
         },
         "url": {
          "type": "string"
         },
         "event": {
          "type": "string",
          "description": "in | out | all"
         },
         "token": {
          "type": "string"
         },
         "skip_if_no_code": {
          "type": "boolean"
         },
         "virtual_accounts": {
          "type": "array"
         },
         "status": {
          "type": "string",
          "description": "active | inactive"
         }
        },
        "required": []
       },
       "example": {
        "status": "inactive"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 12,
          "name": "Đơn hàng website",
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "url": "https://example.com/tinopay/hook",
          "token": "<token>",
          "event": "in",
          "skip_if_no_code": false,
          "virtual_accounts": [
           "9624QA01"
          ],
          "status": "inactive",
          "created_at": "2026-10-20T10:10:00+07:00",
          "updated_at": "2026-10-20T10:10:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "tinopay_delete_webhooks_webhook",
    "summary": "Delete a webhook",
    "description": "Delete a webhook together with all of its logs.",
    "tags": [
     "Webhooks"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-delete-webhooks-webhook"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "webhook",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Webhook ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/webhook-logs": {
   "get": {
    "operationId": "tinopay_get_webhook_logs",
    "summary": "Webhook logs",
    "description": "Every webhook delivery: the request sent, the HTTP status received (`status_code`), `success`, the response. Filter by `webhook_id`, `transaction_id`, `status` (`success`, `failed`); paginated.",
    "tags": [
     "Webhooks"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-webhook-logs"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "webhook_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "transaction_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "success | failed"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 3301,
           "webhook_id": 12,
           "transaction_id": 98213,
           "method": "POST",
           "request_url": "https://example.com/tinopay/hook",
           "request": {
            "transaction_id": "20261020083338000006",
            "transferAmount": 150000,
            "virtualAccount": "9624QA01"
           },
           "status_code": 500,
           "success": false,
           "response": "…",
           "created_at": "2026-10-20T08:33:41+07:00"
          }
         ],
         "meta": {
          "page": 1,
          "per_page": 20,
          "total": 1,
          "last_page": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/webhook-logs/{log}/resend": {
   "post": {
    "operationId": "tinopay_post_webhook_logs_log_resend",
    "summary": "Resend a webhook log",
    "description": "Resend exactly that log's request to the same webhook. Returns 202 `{log_id, queued}`.",
    "tags": [
     "Webhooks"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-webhook-logs-log-resend"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "log",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Webhook log ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "log_id": 3301,
          "queued": true
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/transactions": {
   "get": {
    "operationId": "tinopay_get_transactions",
    "summary": "Transaction history",
    "description": "Newest first, with fields named like the webhook payload (`transactionDate` in ISO 8601). Filters: `bank_account_id`, `virtual_account` (exact VA number), `type` (`in`, `out`), `from`, `to` (`Y-m-d`, by transaction date), `q` (description, transaction code, VA number, reference code), `webhook_status` (`none` not sent, `failed`, `success`); paginated, `per_page` up to 100.",
    "tags": [
     "Transactions"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-transactions"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank_account_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "virtual_account",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Số VA chính xác"
      }
     },
     {
      "name": "type",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "in | out"
      }
     },
     {
      "name": "from",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Y-m-d"
      }
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Y-m-d"
      }
     },
     {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Nội dung, mã giao dịch, số VA, mã tham chiếu"
      }
     },
     {
      "name": "webhook_status",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "none | failed | success"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "≤ 100"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 98213,
           "transaction_id": "20261020083338000006",
           "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
           "gateway": "BIDV",
           "accountNumber": "96240000001",
           "virtualAccount": "9624QA01",
           "content": "DH12345 chuyen tien mua hang",
           "transferType": "in",
           "transferAmount": 150000,
           "referenceCode": "0551dTCO-82LiomOss",
           "transactionDate": "2026-10-20T08:33:38+07:00",
           "created_at": "2026-10-20T08:33:40+07:00"
          }
         ],
         "meta": {
          "page": 1,
          "per_page": 20,
          "total": 1,
          "last_page": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/transactions/summary": {
   "get": {
    "operationId": "tinopay_get_transactions_summary",
    "summary": "Transaction summary",
    "description": "Same filters as the transaction history, not paginated: `{count, total_in, total_out}`.",
    "tags": [
     "Transactions"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-transactions-summary"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank_account_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "virtual_account",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "type",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "in | out"
      }
     },
     {
      "name": "from",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Y-m-d"
      }
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Y-m-d"
      }
     },
     {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "webhook_status",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "none | failed | success"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "count": 2,
          "total_in": 100000,
          "total_out": 30000
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/transactions/{transaction}": {
   "get": {
    "operationId": "tinopay_get_transactions_transaction",
    "summary": "Transaction details",
    "description": "One transaction, by its `id` in the transaction history.",
    "tags": [
     "Transactions"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-transactions-transaction"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "transaction",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Transaction ID (`id` in the transaction history, not the bank's `transaction_id`)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 98213,
          "transaction_id": "20261020083338000006",
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "gateway": "BIDV",
          "accountNumber": "96240000001",
          "virtualAccount": "9624QA01",
          "content": "DH12345 chuyen tien mua hang",
          "transferType": "in",
          "transferAmount": 150000,
          "referenceCode": "0551dTCO-82LiomOss",
          "transactionDate": "2026-10-20T08:33:38+07:00",
          "created_at": "2026-10-20T08:33:40+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/transactions/{transaction}/resend-webhook": {
   "post": {
    "operationId": "tinopay_post_transactions_transaction_resend_webhook",
    "summary": "Resend webhooks for a transaction",
    "description": "Send the transaction again to the bank account's active webhooks. Returns 202 `{transaction_id, queued}`.",
    "tags": [
     "Transactions"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-transactions-transaction-resend-webhook"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "transaction",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Transaction ID (`id` in the transaction history, not the bank's `transaction_id`)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "transaction_id": 98213,
          "queued": true
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/notification-apps/bot-info": {
   "post": {
    "operationId": "tinopay_post_notification_apps_bot_info",
    "summary": "Check a bot token",
    "description": "Step 1 when adding a notification app with your own bot: `type` (`telegram`, `zalo`) and the `bot_token` just entered, or `app_id` to use that app's stored token (when editing). Returns `{valid, bot_name, error}`: when `valid` is `false`, show `error`. See [Telegram, Zalo and Lark notifications](/en/docs/tinopay-notifications).",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-notification-apps-bot-info"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string",
          "description": "telegram | zalo"
         },
         "bot_token": {
          "type": "string"
         },
         "app_id": {
          "type": "integer"
         }
        },
        "required": []
       },
       "example": {
        "type": "zalo",
        "bot_token": "<bot_token>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "valid": true,
          "bot_name": "Bot Cửa hàng ABC",
          "error": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/notification-apps/find-chats": {
   "post": {
    "operationId": "tinopay_post_notification_apps_find_chats",
    "summary": "Find a bot's chats",
    "description": "Step 2: returns `{chats: [{id, title, type}], error}`; pick one `id` as the `endpoint`. Telegram: groups and people that messaged the bot in the last 24 hours; a non-null `error` (the bot is attached to another system's webhook) means entering the ID by hand. Zalo keeps no old messages: the request waits up to about 20 seconds and only catches messages sent to the bot meanwhile (groups: mention the bot); set the HTTP timeout to at least 30 seconds, and `chats` is empty when nothing arrives. Not retried on network errors.",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-notification-apps-find-chats"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string",
          "description": "telegram | zalo"
         },
         "bot_token": {
          "type": "string"
         },
         "app_id": {
          "type": "integer"
         }
        },
        "required": []
       },
       "example": {
        "type": "zalo",
        "bot_token": "<bot_token>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "chats": [
           {
            "id": "zgr-1a2b3c4d5e6f7a8b9c0d",
            "title": "Nhóm kế toán",
            "type": "group"
           }
          ],
          "error": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/notification-apps/test": {
   "post": {
    "operationId": "tinopay_post_notification_apps_test",
    "summary": "Send a test message",
    "description": "Step 3: sends a real test message to `endpoint` (group or chat ID, or Lark webhook URL) before saving. Returns `{connected, chat_title}` (`chat_title` for Telegram only); save only when `connected` is `true`. Telegram without `bot_token` tests with the shared bot. Not retried on network errors.",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-notification-apps-test"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string",
          "description": "telegram | zalo | lark"
         },
         "endpoint": {
          "type": "string",
          "description": "ID nhóm/chat, hoặc URL webhook Lark"
         },
         "bot_token": {
          "type": "string"
         },
         "app_id": {
          "type": "integer"
         }
        },
        "required": []
       },
       "example": {
        "type": "telegram",
        "endpoint": "-1001234567890"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "connected": true,
          "chat_title": "Kế toán ABC"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/notification-apps": {
   "get": {
    "operationId": "tinopay_get_notification_apps",
    "summary": "List notification apps",
    "description": "Apps that post transaction notifications to Telegram, Zalo or Lark; filter by `type`, `bank_account_id`. `bot`: `allpay` (shared bot), `own` (your bot), `null` for Lark. `bot_token` is never returned, only `bot_token_masked`. A non-null `last_error`: the latest delivery failed (token revoked, bot removed from the group…); it goes back to `null` after a successful delivery.",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-notification-apps"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "type",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "telegram | zalo | lark"
      }
     },
     {
      "name": "bank_account_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 7,
           "type": "zalo",
           "name": "Nhóm kế toán",
           "endpoint": "zgr-1a2b3c4d5e6f7a8b9c0d",
           "bot": "own",
           "bot_token_masked": "<masked>",
           "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
           "virtual_accounts": [
            "9624QA01"
           ],
           "status": "active",
           "last_error": null,
           "last_error_at": null,
           "created_at": "2026-10-22T09:00:00+07:00",
           "updated_at": "2026-10-22T09:00:00+07:00"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "tinopay_post_notification_apps",
    "summary": "Create a notification app",
    "description": "Step 4. `type` cannot change after creation. `bot_token`: required for Zalo (your own bot); for Telegram, given means your own bot, empty means the shared bot @allpay_telebot (`endpoint` is a group ID starting with `-`); not sent for Lark (`endpoint` is the Lark bot webhook URL). `virtual_accounts`: VA numbers of that bank account, empty means every VA. Returns 201.",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-notification-apps"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string",
          "description": "telegram | zalo | lark (không đổi được sau khi tạo)"
         },
         "name": {
          "type": "string",
          "description": "≤ 250"
         },
         "endpoint": {
          "type": "string"
         },
         "bot_token": {
          "type": "string"
         },
         "bank_account_id": {
          "type": "string"
         },
         "virtual_accounts": {
          "type": "array"
         },
         "status": {
          "type": "string",
          "description": "active | inactive"
         }
        },
        "required": [
         "type",
         "name",
         "endpoint",
         "bank_account_id"
        ]
       },
       "example": {
        "type": "zalo",
        "name": "Nhóm kế toán",
        "endpoint": "zgr-1a2b3c4d5e6f7a8b9c0d",
        "bot_token": "<bot_token>",
        "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
        "virtual_accounts": [
         "9624QA01"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 7,
          "type": "zalo",
          "name": "Nhóm kế toán",
          "endpoint": "zgr-1a2b3c4d5e6f7a8b9c0d",
          "bot": "own",
          "bot_token_masked": "<masked>",
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "virtual_accounts": [
           "9624QA01"
          ],
          "status": "active",
          "last_error": null,
          "last_error_at": null,
          "created_at": "2026-10-22T09:00:00+07:00",
          "updated_at": "2026-10-22T09:00:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/notification-apps/{app}": {
   "get": {
    "operationId": "tinopay_get_notification_apps_app",
    "summary": "Notification app details",
    "description": "One notification app of the merchant; one that does not belong to the merchant returns 404 `RESOURCE_NOT_FOUND`.",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-notification-apps-app"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "app",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Notification app ID (`id` in the notification app list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 7,
          "type": "zalo",
          "name": "Nhóm kế toán",
          "endpoint": "zgr-1a2b3c4d5e6f7a8b9c0d",
          "bot": "own",
          "bot_token_masked": "<masked>",
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "virtual_accounts": [
           "9624QA01"
          ],
          "status": "active",
          "last_error": null,
          "last_error_at": null,
          "created_at": "2026-10-22T09:00:00+07:00",
          "updated_at": "2026-10-22T09:00:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "patch": {
    "operationId": "tinopay_patch_notification_apps_app",
    "summary": "Update a notification app",
    "description": "Send only the fields to change, as a JSON body, never `type`. No `bot_token`: keep the stored token; a new string: replace it; `bot_token: null`: Telegram goes back to the shared bot (then `endpoint` must be a group ID `-…`); Zalo cannot drop its token. A `bank_account_id` that does not belong to the merchant: 404 `BANK_ACCOUNT_NOT_FOUND`.",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-patch-notification-apps-app"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "app",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Notification app ID (`id` in the notification app list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "endpoint": {
          "type": "string"
         },
         "bot_token": {
          "type": "string"
         },
         "bank_account_id": {
          "type": "string"
         },
         "virtual_accounts": {
          "type": "array"
         },
         "status": {
          "type": "string",
          "description": "active | inactive"
         }
        },
        "required": []
       },
       "example": {
        "status": "inactive"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "tinopay_delete_notification_apps_app",
    "summary": "Delete a notification app",
    "description": "Delete one notification app of the merchant.",
    "tags": [
     "Notifications"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-delete-notification-apps-app"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "app",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Notification app ID (`id` in the notification app list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/sapo-integrations/test": {
   "post": {
    "operationId": "tinopay_post_sapo_integrations_test",
    "summary": "Test the Sapo connection",
    "description": "Before saving: body `store_url`, `api_key`, `api_secret` of the private app on Sapo; when editing, send `integration_id` instead of `api_secret` to use the saved secret. Returns HTTP 200 `{connected, error}`; with `connected: false`, `error` gives the reason.",
    "tags": [
     "Sapo integration"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-sapo-integrations-test"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "store_url": {
          "type": "string",
          "description": "<tên-cửa-hàng>.mysapo.net"
         },
         "api_key": {
          "type": "string"
         },
         "api_secret": {
          "type": "string"
         },
         "integration_id": {
          "type": "integer"
         }
        },
        "required": []
       },
       "example": {
        "store_url": "<tên-cửa-hàng>.mysapo.net",
        "api_key": "<api_key>",
        "api_secret": "<api_secret>"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "connected": true,
          "error": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/sapo-integrations": {
   "get": {
    "operationId": "tinopay_get_sapo_integrations",
    "summary": "List Sapo integrations",
    "description": "Sapo integrations of the merchant, filtered by the query `bank_account_id`. `api_secret` is never returned (only `has_api_secret`); a non-null `last_error` is a Sapo connection error; `snippet` is the code to paste into Sapo's checkout page.",
    "tags": [
     "Sapo integration"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-sapo-integrations"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "bank_account_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 4,
           "name": "Website Sapo",
           "store_url": "<tên-cửa-hàng>.mysapo.net",
           "api_key": "<api_key>",
           "has_api_secret": true,
           "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
           "virtual_account": "9624QA01",
           "order_prefix": "TNG",
           "transaction": {
            "kind": "capture",
            "source_name": null,
            "status": null
           },
           "status": "active",
           "script_url": "<script_url>",
           "snippet": "<snippet>",
           "last_error": null,
           "last_error_at": null,
           "last_paid_at": "2026-10-24T10:00:00+07:00",
           "created_at": "2026-10-24T09:00:00+07:00",
           "updated_at": "2026-10-24T09:00:00+07:00"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "tinopay_post_sapo_integrations",
    "summary": "Create a Sapo integration",
    "description": "The buyer transfers with content holding the order code (prefix + Sapo order number, e.g. `TNG1002` for order #1002): when the amount is enough or more, TinoPay marks the order paid on Sapo. Body: `name` (≤ 100 characters), `store_url` (the store's `.mysapo.net` domain; custom domains are not accepted), `api_key`, `api_secret` (private app on Sapo with read and write access to orders and transactions), `bank_account_id`, `virtual_account` (required for BIDV), `order_prefix` (2–5 letters or digits; when missing from the payment code patterns, TinoPay adds a pattern with a 1–12 digit suffix), `transaction` (`kind`, `source_name`, `status`), `status`. TinoPay tests the Sapo connection before saving; on failure 422 `SAPO_CONNECTION_FAILED` and nothing is created. Paste the returned `snippet` into Sapo Admin → Cấu hình → Trang thanh toán (Settings → Checkout), the additional message field.",
    "tags": [
     "Sapo integration"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-sapo-integrations"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "≤ 100"
         },
         "store_url": {
          "type": "string",
          "description": "<tên-cửa-hàng>.mysapo.net (tên miền riêng không nhận)"
         },
         "api_key": {
          "type": "string"
         },
         "api_secret": {
          "type": "string"
         },
         "bank_account_id": {
          "type": "string"
         },
         "virtual_account": {
          "type": "string",
          "description": "Bắt buộc với BIDV"
         },
         "order_prefix": {
          "type": "string",
          "description": "2–5 chữ/số"
         },
         "transaction": {
          "type": "array"
         },
         "status": {
          "type": "string",
          "description": "active | inactive"
         }
        },
        "required": [
         "name",
         "store_url",
         "api_key",
         "api_secret",
         "bank_account_id",
         "order_prefix"
        ]
       },
       "example": {
        "name": "Website Sapo",
        "store_url": "<tên-cửa-hàng>.mysapo.net",
        "api_key": "<api_key>",
        "api_secret": "<api_secret>",
        "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
        "virtual_account": "9624QA01",
        "order_prefix": "TNG"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 4,
          "name": "Website Sapo",
          "store_url": "<tên-cửa-hàng>.mysapo.net",
          "api_key": "<api_key>",
          "has_api_secret": true,
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "virtual_account": "9624QA01",
          "order_prefix": "TNG",
          "transaction": {
           "kind": "capture",
           "source_name": null,
           "status": null
          },
          "status": "active",
          "script_url": "<script_url>",
          "snippet": "<snippet>",
          "last_error": null,
          "last_error_at": null,
          "last_paid_at": "2026-10-24T10:00:00+07:00",
          "created_at": "2026-10-24T09:00:00+07:00",
          "updated_at": "2026-10-24T09:00:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/sapo-integrations/{integration}": {
   "get": {
    "operationId": "tinopay_get_sapo_integrations_integration",
    "summary": "Get a Sapo integration",
    "description": "One Sapo integration, same shape as a list item; `api_secret` is not returned.",
    "tags": [
     "Sapo integration"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-sapo-integrations-integration"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "integration",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Sapo integration ID (`id` in the Sapo integration list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 4,
          "name": "Website Sapo",
          "store_url": "<tên-cửa-hàng>.mysapo.net",
          "api_key": "<api_key>",
          "has_api_secret": true,
          "bank_account_id": "9c1e6f2a-5b7d-4e1a-9f3c-2d8b6a4e0c11",
          "virtual_account": "9624QA01",
          "order_prefix": "TNG",
          "transaction": {
           "kind": "capture",
           "source_name": null,
           "status": null
          },
          "status": "active",
          "script_url": "<script_url>",
          "snippet": "<snippet>",
          "last_error": null,
          "last_error_at": null,
          "last_paid_at": "2026-10-24T10:00:00+07:00",
          "created_at": "2026-10-24T09:00:00+07:00",
          "updated_at": "2026-10-24T09:00:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "patch": {
    "operationId": "tinopay_patch_sapo_integrations_integration",
    "summary": "Update a Sapo integration",
    "description": "Send only the changed fields. Leaving out `api_secret` keeps the saved secret; TinoPay tests the Sapo connection again only when `store_url`, `api_key` or `api_secret` changes (failure: 422 `SAPO_CONNECTION_FAILED`). A `bank_account_id` outside the merchant: 404 `BANK_ACCOUNT_NOT_FOUND`.",
    "tags": [
     "Sapo integration"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-patch-sapo-integrations-integration"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "integration",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Sapo integration ID (`id` in the Sapo integration list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         },
         "store_url": {
          "type": "string"
         },
         "api_key": {
          "type": "string"
         },
         "api_secret": {
          "type": "string"
         },
         "bank_account_id": {
          "type": "string"
         },
         "virtual_account": {
          "type": "string"
         },
         "order_prefix": {
          "type": "string"
         },
         "transaction": {
          "type": "array"
         },
         "status": {
          "type": "string",
          "description": "active | inactive"
         }
        },
        "required": []
       },
       "example": {
        "status": "inactive"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "tinopay_delete_sapo_integrations_integration",
    "summary": "Delete a Sapo integration",
    "description": "Deletes it together with its reconciliation log. Also remove the snippet pasted on Sapo.",
    "tags": [
     "Sapo integration"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-delete-sapo-integrations-integration"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "integration",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Sapo integration ID (`id` in the Sapo integration list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/sapo-order-logs": {
   "get": {
    "operationId": "tinopay_get_sapo_order_logs",
    "summary": "Sapo reconciliation log",
    "description": "Transactions matched against Sapo orders. Query: `integration_id`, `transaction_id`, `status`, `page`, `per_page`. `status`: `paid` (recorded; `message` notes any overpayment), `underpaid` (underpaid, not recorded), `already_paid` (order already paid), `not_found` (no order for the code in the transfer content), `cancelled` (order cancelled), `error` (Sapo refused or could not be reached, see `message`). To reconcile a transaction again: [resend the transaction's webhook](/en/docs/api/tinopay-post-transactions-transaction-resend-webhook); a paid order is never recorded twice.",
    "tags": [
     "Sapo integration"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-sapo-order-logs"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "integration_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "transaction_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 801,
           "integration_id": 4,
           "transaction_id": 98213,
           "sapo_order_id": 1002,
           "order_name": "#1002",
           "amount": 150000,
           "order_total": 150000,
           "status": "paid",
           "message": null,
           "created_at": "2026-10-24T10:00:00+07:00"
          }
         ],
         "meta": {
          "page": 1,
          "per_page": 20,
          "total": 1,
          "last_page": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/api-tokens": {
   "get": {
    "operationId": "tinopay_get_api_tokens",
    "summary": "List API tokens",
    "description": "Tokens for calling TinoPay's public `GET /api/transactions` API (`Authorization: Bearer <token>`). Returns `[{id, name, last_used_at, created_at}]`; the token string is never returned again (TinoPay stores only a hash).",
    "tags": [
     "API tokens"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-get-api-tokens"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": 3,
           "name": "Website",
           "last_used_at": "2026-10-22T09:00:00+07:00",
           "created_at": "2026-10-20T10:00:00+07:00"
          }
         ]
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "tinopay_post_api_tokens",
    "summary": "Create an API token",
    "description": "Returns 201 `{id, name, last_used_at, created_at, token}`: `token` (64 characters) appears only in this response; show it to the customer once, do not store or log it. Not retried on network errors (each call creates a token): read the list again and revoke any extra token.",
    "tags": [
     "API tokens"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-post-api-tokens"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string"
         }
        },
        "required": []
       },
       "example": {
        "name": "Website"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": 3,
          "name": "Website",
          "last_used_at": null,
          "created_at": "2026-10-20T10:00:00+07:00",
          "token": "<token>"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/tinopay/api-tokens/{token}": {
   "delete": {
    "operationId": "tinopay_delete_api_tokens_token",
    "summary": "Revoke an API token",
    "description": "Revoke the token, effective immediately.",
    "tags": [
     "API tokens"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/tinopay-delete-api-tokens-token"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPay service ID"
      }
     },
     {
      "name": "token",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "API token ID (`id` in the API token list, not the token string)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime": {
   "get": {
    "operationId": "uptime_get_overview",
    "summary": "Tino Uptime plan overview",
    "description": "The current plan (`subscription`: plan code, plan name, `limits`, where the plan is changed `manage_hint`), usage (`usage`), monitor counts by state (`monitor`) and `login_url`: the link that opens the Tino Uptime dashboard (sign in with the Tino account) for what has no API here (status pages, servers, WordPress, CVE). A service that is no longer the customer's current plan answers 404 `service_not_linked`.",
    "tags": [
     "Uptime plan"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-overview"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "account": {
           "external_id": "12345",
           "name": "Công ty ABC",
           "status": "active",
           "plan_code": "plus",
           "billing_source": "hostbill",
           "external_ref": "100002",
           "created_at": "2026-10-20T15:00:00+07:00"
          },
          "subscription": {
           "plan_code": "plus",
           "plan_name": "Plus",
           "billing_source": "hostbill",
           "status": "active",
           "period_start": "2026-10-20T15:00:00+07:00",
           "period_end": null,
           "limits": {
            "max_monitors": 25,
            "min_interval_s": 60,
            "raw_retention_days": 90,
            "status_pages": 3,
            "status_page_subscribers": 500,
            "agent_hosts": 5,
            "wp_sites": 5,
            "locations": [
             "vn-cmc",
             "vn-vt",
             "intl"
            ],
            "channels": [
             "email",
             "telegram",
             "discord",
             "slack",
             "webhook"
            ],
            "cve_alerts": true,
            "cve": true
           },
           "flags": [],
           "manage_hint": "hostbill"
          },
          "usage": {
           "monitors": 3,
           "status_pages": 1,
           "agent_hosts": 0,
           "wp_sites": 0,
           "monitors_paused_by_plan": 0,
           "limits": {
            "max_monitors": 25,
            "min_interval_s": 60,
            "raw_retention_days": 90,
            "status_pages": 3,
            "status_page_subscribers": 500,
            "agent_hosts": 5,
            "wp_sites": 5,
            "locations": [
             "vn-cmc",
             "vn-vt",
             "intl"
            ],
            "channels": [
             "email",
             "telegram",
             "discord",
             "slack",
             "webhook"
            ],
            "cve_alerts": true,
            "cve": true
           }
          },
          "monitor": {
           "total": 3,
           "up": 2,
           "down": 0,
           "paused": 1
          },
          "login_url": "https://uptime.tino.vn/login/tino?return_to=/"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/usage": {
   "get": {
    "operationId": "uptime_get_usage",
    "summary": "Usage against plan limits",
    "description": "Monitors, status pages, servers and WordPress sites in use against the plan's `limits`; `monitors_paused_by_plan` counts monitors paused for exceeding the limits after a downgrade.",
    "tags": [
     "Uptime plan"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-usage"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "monitors": 3,
          "status_pages": 1,
          "agent_hosts": 0,
          "wp_sites": 0,
          "monitors_paused_by_plan": 0,
          "limits": {
           "max_monitors": 25,
           "min_interval_s": 60,
           "raw_retention_days": 90,
           "status_pages": 3,
           "status_page_subscribers": 500,
           "agent_hosts": 5,
           "wp_sites": 5,
           "locations": [
            "vn-cmc",
            "vn-vt",
            "intl"
           ],
           "channels": [
            "email",
            "telegram",
            "discord",
            "slack",
            "webhook"
           ],
           "cve_alerts": true,
           "cve": true
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/monitors": {
   "get": {
    "operationId": "uptime_get_monitors",
    "summary": "List monitors",
    "description": "The account's monitors, filtered by state (`state`) and type (`type`), searched by name or target (`q`); cursor pagination (`next_cursor`). Each monitor has its latest state, last check, latency, open incident and 30-day uptime.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-monitors"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "state",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Filter by state: `pending`, `up`, `suspect`, `down`, `partial`, `down_international`, `paused`"
      }
     },
     {
      "name": "type",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Filter by type (`settings.type`)"
      }
     },
     {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Search the name or target, case-insensitive"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Items per page, default 50, at most 100"
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`next_cursor` of the previous page; omit for the first page"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "data": [
           {
            "id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
            "name": "Website chính",
            "interval_s": 60,
            "locations": [
             "vn-cmc",
             "vn-vt",
             "intl"
            ],
            "enabled": true,
            "paused_until": null,
            "snoozed_until": null,
            "disabled_reason": null,
            "verified": true,
            "created_at": "2026-10-24T08:00:00+07:00",
            "settings": {
             "type": "http",
             "url": "https://example.com/",
             "method": "GET",
             "expected_status": [
              200
             ],
             "follow_redirects": true,
             "header_names": [],
             "basic_auth_set": false,
             "body_set": false
            },
            "international_critical": false,
            "state": "up",
            "state_since": "2026-10-24T09:15:00+07:00",
            "last_check_at": "2026-10-24T10:30:00+07:00",
            "last_latency_ms": 182,
            "last_error_kind": null,
            "current_incident_id": null,
            "ssl_expires_at": "2027-01-15T07:00:00+07:00",
            "domain_expires_at": null,
            "uptime_30d": 99.98
           }
          ],
          "next_cursor": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "uptime_post_monitors",
    "summary": "Create a monitor",
    "description": "JSON body: name, interval, probe locations and `settings` for the [monitor type](/en/docs/uptime-start#monitor-types). Tino Uptime runs the first check right away and waits up to 10 seconds: the result is in `first_check` (`status: pending` past that). A heartbeat monitor's `settings.ping_url` appears only in this answer. HTTP 201. Over a plan limit (monitor count, interval, location) answers 403 `entitlement_exceeded`; an internal or unsafe target answers 422 `validation_failed` (`details.reason: blocked_destination`); a target checked too often answers 422 `target_rate_exceeded`.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-post-monitors"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Tên monitor, 1–200 ký tự"
         },
         "interval_s": {
          "type": "integer",
          "description": "Chu kỳ kiểm (giây), 30–86400, không dưới `limits.min_interval_s` của gói"
         },
         "locations": {
          "type": "array",
          "description": "Vị trí dò, tối đa 10, trong `limits.locations` của gói (`vn-cmc`, `vn-vt`, `intl`)"
         },
         "settings": {
          "type": "object",
          "description": "Loại và đích kiểm: `type` là `http`, `keyword`, `ssl`, `domain`, `ping`, `tcp`, `dns` hoặc `heartbeat`, trường theo loại ở [Bắt đầu với Tino Uptime](/docs/uptime-start#loai-monitor)"
         },
         "international_critical": {
          "type": "boolean",
          "description": "`true`: chỉ điểm dò quốc tế lỗi cũng tính là down; mặc định `false`"
         },
         "idempotency_key": {
          "type": "string",
          "description": "8–128 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng body thì không tạo thêm"
         }
        },
        "required": [
         "name",
         "interval_s",
         "settings"
        ]
       },
       "example": {
        "name": "Website chính",
        "interval_s": 60,
        "locations": [
         "vn-cmc",
         "vn-vt",
         "intl"
        ],
        "settings": {
         "type": "http",
         "url": "https://example.com/",
         "expected_status": [
          200
         ]
        },
        "idempotency_key": "website-chinh-0001"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
          "name": "Website chính",
          "interval_s": 60,
          "locations": [
           "vn-cmc",
           "vn-vt",
           "intl"
          ],
          "enabled": true,
          "paused_until": null,
          "snoozed_until": null,
          "disabled_reason": null,
          "verified": true,
          "created_at": "2026-10-24T08:00:00+07:00",
          "settings": {
           "type": "http",
           "url": "https://example.com/",
           "method": "GET",
           "expected_status": [
            200
           ],
           "follow_redirects": true,
           "header_names": [],
           "basic_auth_set": false,
           "body_set": false
          },
          "international_critical": false,
          "state": "pending",
          "state_since": null,
          "last_check_at": null,
          "last_latency_ms": null,
          "last_error_kind": null,
          "current_incident_id": null,
          "ssl_expires_at": null,
          "domain_expires_at": null,
          "uptime_30d": null,
          "first_check": {
           "status": "done",
           "outcome": "ok",
           "latency_ms": 182,
           "status_code": 200,
           "error_kind": null,
           "location": "vn-cmc",
           "reason": null
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/monitors/{monitor}": {
   "get": {
    "operationId": "uptime_get_monitors_monitor",
    "summary": "Monitor details",
    "description": "Settings, state, last check, open incident (`current_incident_id`), SSL expiry, domain expiry, 30-day uptime. Headers, body and the Basic auth password are never returned: `settings` only has `header_names`, `body_set`, `basic_auth_set`.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-monitors-monitor"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
          "name": "Website chính",
          "interval_s": 60,
          "locations": [
           "vn-cmc",
           "vn-vt",
           "intl"
          ],
          "enabled": true,
          "paused_until": null,
          "snoozed_until": null,
          "disabled_reason": null,
          "verified": true,
          "created_at": "2026-10-24T08:00:00+07:00",
          "settings": {
           "type": "http",
           "url": "https://example.com/",
           "method": "GET",
           "expected_status": [
            200
           ],
           "follow_redirects": true,
           "header_names": [],
           "basic_auth_set": false,
           "body_set": false
          },
          "international_critical": false,
          "state": "up",
          "state_since": "2026-10-24T09:15:00+07:00",
          "last_check_at": "2026-10-24T10:30:00+07:00",
          "last_latency_ms": 182,
          "last_error_kind": null,
          "current_incident_id": null,
          "ssl_expires_at": "2027-01-15T07:00:00+07:00",
          "domain_expires_at": null,
          "uptime_30d": 99.98
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "put": {
    "operationId": "uptime_put_monitors_monitor",
    "summary": "Update a monitor",
    "description": "Send only the fields to change, as a JSON body. `settings` carries every required field of its type; for `http`, `keyword`: omit `headers`, `body`, `basic_auth` to keep them, `headers: {}` or `body: \"\"` to remove, `clear_basic_auth: true` to remove Basic auth. `enabled: false` turns the monitor off.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-put-monitors-monitor"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Tên monitor, 1–200 ký tự"
         },
         "interval_s": {
          "type": "integer",
          "description": "Chu kỳ kiểm (giây), 30–86400, không dưới `limits.min_interval_s` của gói"
         },
         "locations": {
          "type": "array",
          "description": "Vị trí dò, tối đa 10, trong `limits.locations` của gói (`vn-cmc`, `vn-vt`, `intl`)"
         },
         "enabled": {
          "type": "boolean",
          "description": "`false` tắt monitor (giữ cấu hình), `true` bật lại"
         },
         "settings": {
          "type": "object",
          "description": "Loại và đích kiểm: `type` là `http`, `keyword`, `ssl`, `domain`, `ping`, `tcp`, `dns` hoặc `heartbeat`, trường theo loại ở [Bắt đầu với Tino Uptime](/docs/uptime-start#loai-monitor)"
         },
         "international_critical": {
          "type": "boolean",
          "description": "`true`: chỉ điểm dò quốc tế lỗi cũng tính là down; mặc định `false`"
         }
        },
        "required": []
       },
       "example": {
        "interval_s": 120
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
          "name": "Website chính",
          "interval_s": 120,
          "locations": [
           "vn-cmc",
           "vn-vt",
           "intl"
          ],
          "enabled": true,
          "paused_until": null,
          "snoozed_until": null,
          "disabled_reason": null,
          "verified": true,
          "created_at": "2026-10-24T08:00:00+07:00",
          "settings": {
           "type": "http",
           "url": "https://example.com/",
           "method": "GET",
           "expected_status": [
            200
           ],
           "follow_redirects": true,
           "header_names": [],
           "basic_auth_set": false,
           "body_set": false
          },
          "international_critical": false,
          "state": "up",
          "state_since": "2026-10-24T09:15:00+07:00",
          "last_check_at": "2026-10-24T10:30:00+07:00",
          "last_latency_ms": 182,
          "last_error_kind": null,
          "current_incident_id": null,
          "ssl_expires_at": "2027-01-15T07:00:00+07:00",
          "domain_expires_at": null,
          "uptime_30d": 99.98
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "uptime_delete_monitors_monitor",
    "summary": "Delete a monitor",
    "description": "Deletes the monitor. HTTP 204, no content.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-delete-monitors-monitor"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/monitors/{monitor}/pause": {
   "post": {
    "operationId": "uptime_post_monitors_monitor_pause",
    "summary": "Pause a monitor",
    "description": "Stops the monitor's checks and alerts (`enabled: false`), keeping its settings. Returns the monitor.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-post-monitors-monitor-pause"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
          "name": "Website chính",
          "interval_s": 60,
          "locations": [
           "vn-cmc",
           "vn-vt",
           "intl"
          ],
          "enabled": false,
          "paused_until": null,
          "snoozed_until": null,
          "disabled_reason": null,
          "verified": true,
          "created_at": "2026-10-24T08:00:00+07:00",
          "settings": {
           "type": "http",
           "url": "https://example.com/",
           "method": "GET",
           "expected_status": [
            200
           ],
           "follow_redirects": true,
           "header_names": [],
           "basic_auth_set": false,
           "body_set": false
          },
          "international_critical": false,
          "state": "paused",
          "state_since": "2026-10-24T10:31:00+07:00",
          "last_check_at": "2026-10-24T10:30:00+07:00",
          "last_latency_ms": 182,
          "last_error_kind": null,
          "current_incident_id": null,
          "ssl_expires_at": "2027-01-15T07:00:00+07:00",
          "domain_expires_at": null,
          "uptime_30d": 99.98
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/monitors/{monitor}/resume": {
   "post": {
    "operationId": "uptime_post_monitors_monitor_resume",
    "summary": "Resume a monitor",
    "description": "Turns a paused monitor back on. Returns the monitor.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-post-monitors-monitor-resume"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
          "name": "Website chính",
          "interval_s": 60,
          "locations": [
           "vn-cmc",
           "vn-vt",
           "intl"
          ],
          "enabled": true,
          "paused_until": null,
          "snoozed_until": null,
          "disabled_reason": null,
          "verified": true,
          "created_at": "2026-10-24T08:00:00+07:00",
          "settings": {
           "type": "http",
           "url": "https://example.com/",
           "method": "GET",
           "expected_status": [
            200
           ],
           "follow_redirects": true,
           "header_names": [],
           "basic_auth_set": false,
           "body_set": false
          },
          "international_critical": false,
          "state": "pending",
          "state_since": null,
          "last_check_at": "2026-10-24T10:30:00+07:00",
          "last_latency_ms": 182,
          "last_error_kind": null,
          "current_incident_id": null,
          "ssl_expires_at": "2027-01-15T07:00:00+07:00",
          "domain_expires_at": null,
          "uptime_30d": 99.98
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/monitors/{monitor}/uptime": {
   "get": {
    "operationId": "uptime_get_monitors_monitor_uptime",
    "summary": "Monitor uptime",
    "description": "Uptime for the `24h`, `7d`, `30d`, `90d` windows (`uptime_pct`, checks, downtime, average latency; the `7d` window adds p95) and one month's SLA (`month=YYYY-MM`, Vietnam time). Available on every plan.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-monitors-monitor-uptime"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     },
     {
      "name": "windows",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Windows to compute, comma-separated: `24h`, `7d`, `30d`, `90d` (all four by default)"
      }
     },
     {
      "name": "month",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`YYYY-MM`: adds that month's SLA (Vietnam time, last 13 months)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "windows": [
           {
            "window": "24h",
            "days": 1,
            "checks": 4320,
            "uptime_pct": 100,
            "avg_latency_ms": 176.4,
            "downtime_s": 0,
            "no_data": false
           },
           {
            "window": "30d",
            "days": 30,
            "checks": 129600,
            "uptime_pct": 99.98,
            "avg_latency_ms": 181.2,
            "downtime_s": 518,
            "no_data": false
           }
          ]
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/monitors/{monitor}/results": {
   "get": {
    "operationId": "uptime_get_monitors_monitor_results",
    "summary": "Monitor check results",
    "description": "`granularity=raw`: each check, newest first, paginated by `cursor` (DNS, connect, TLS, TTFB times, HTTP status, failing step); `1h`, `1d`: hourly or daily points in `points` (p50, p95, average). A plan only sees its last `limits.raw_retention_days` days: older data is cut and `retention_limited` is `true`.",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-monitors-monitor-results"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     },
     {
      "name": "granularity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`raw` (each check, default), `1h` or `1d` (hourly or daily points)"
      }
     },
     {
      "name": "from",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Start (RFC 3339); default 24 hours (raw), 7 days (1h), 90 days (1d) before `to`"
      }
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "End (RFC 3339), default now"
      }
     },
     {
      "name": "location",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Results of one probe location only"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Checks per page with `raw`, default 100, at most 1000"
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`next_cursor` of the previous page; omit for the first page"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "granularity": "1h",
          "from": "2026-10-17T11:00:00+07:00",
          "to": "2026-10-24T11:00:00+07:00",
          "retention_limited": false,
          "data": [],
          "points": [
           {
            "t": "2026-10-24T10:00:00+07:00",
            "valid": 180,
            "ok": 180,
            "p50_ms": 171,
            "p95_ms": 238,
            "avg_ms": 178.5,
            "dns_ms": 12,
            "connect_ms": 21,
            "tls_ms": 35,
            "ttfb_ms": 96
           }
          ],
          "next_cursor": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/monitors/{monitor}/incidents": {
   "get": {
    "operationId": "uptime_get_monitors_monitor_incidents",
    "summary": "Monitor incidents",
    "description": "The incidents of one monitor, cursor pagination (`next_cursor`).",
    "tags": [
     "Monitors"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-monitors-monitor-incidents"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "monitor",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Monitor ID (UUID, `id` in the monitor list)"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Items per page, default 50, at most 100"
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`next_cursor` of the previous page; omit for the first page"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "data": [
           {
            "id": "7a2d9e44-1c3b-4f6a-8e5d-0b9c2a7f4e21",
            "number": 12,
            "subject_kind": "monitor",
            "subject_id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
            "subject_name": "Website chính",
            "state": "resolved",
            "severity": "down",
            "opened_state": "down",
            "tier": "urgent",
            "title": "Website chính không truy cập được",
            "cause_code": null,
            "opened_at": "2026-10-24T09:02:00+07:00",
            "acked_at": null,
            "resolved_at": "2026-10-24T09:15:00+07:00",
            "parent_incident_id": null,
            "children_count": 0,
            "summary": "3/3 vị trí lỗi",
            "evidence": {
             "location": "vn-cmc",
             "captured_at": "2026-10-24T09:02:00+07:00",
             "step": "connect",
             "error": "connection refused",
             "status_line": null,
             "votes": [
              {
               "location": "vn-cmc",
               "region": null,
               "outcome": "fail",
               "error_kind": "connect",
               "cause_code": null,
               "status_code": null,
               "ip": "203.0.113.10",
               "tls_valid": null,
               "at": "2026-10-24T09:02:00+07:00"
              }
             ]
            }
           }
          ],
          "next_cursor": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/incidents": {
   "get": {
    "operationId": "uptime_get_incidents",
    "summary": "List incidents",
    "description": "Incidents of every monitor in the account, filtered by state (`state`; `active` means not closed) and time (`since`). Each incident has a tier (`tier`), state, open, acknowledge and close times, a summary (`summary`) and a fix hint (`cause`).",
    "tags": [
     "Incidents"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-incidents"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "state",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`open`, `ack`, `resolved`, or `active` (`open` and `ack`)"
      }
     },
     {
      "name": "since",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "RFC 3339: incidents opened or closed since then, or still open"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Items per page, default 50, at most 100"
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`next_cursor` of the previous page; omit for the first page"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "data": [
           {
            "id": "7a2d9e44-1c3b-4f6a-8e5d-0b9c2a7f4e21",
            "number": 12,
            "subject_kind": "monitor",
            "subject_id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
            "subject_name": "Website chính",
            "state": "open",
            "severity": "down",
            "opened_state": "down",
            "tier": "urgent",
            "title": "Website chính không truy cập được",
            "cause_code": null,
            "opened_at": "2026-10-24T09:02:00+07:00",
            "acked_at": null,
            "resolved_at": null,
            "parent_incident_id": null,
            "children_count": 0,
            "summary": "3/3 vị trí lỗi",
            "evidence": {
             "location": "vn-cmc",
             "captured_at": "2026-10-24T09:02:00+07:00",
             "step": "connect",
             "error": "connection refused",
             "status_line": null,
             "votes": [
              {
               "location": "vn-cmc",
               "region": null,
               "outcome": "fail",
               "error_kind": "connect",
               "cause_code": null,
               "status_code": null,
               "ip": "203.0.113.10",
               "tls_valid": null,
               "at": "2026-10-24T09:02:00+07:00"
              }
             ]
            }
           }
          ],
          "next_cursor": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/incidents/{incident}": {
   "get": {
    "operationId": "uptime_get_incidents_incident",
    "summary": "Incident details",
    "description": "The incident with the evidence captured when it opened (`evidence`: location, failing step, HTTP status line, each probe location's result) and a fix hint in Vietnamese (`cause`).",
    "tags": [
     "Incidents"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-incidents-incident"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "incident",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Incident ID (UUID, `id` in the incident list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "7a2d9e44-1c3b-4f6a-8e5d-0b9c2a7f4e21",
          "number": 12,
          "subject_kind": "monitor",
          "subject_id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
          "subject_name": "Website chính",
          "state": "resolved",
          "severity": "down",
          "opened_state": "down",
          "tier": "urgent",
          "title": "Website chính không truy cập được",
          "cause_code": null,
          "opened_at": "2026-10-24T09:02:00+07:00",
          "acked_at": null,
          "resolved_at": "2026-10-24T09:15:00+07:00",
          "parent_incident_id": null,
          "children_count": 0,
          "summary": "3/3 vị trí lỗi",
          "evidence": {
           "location": "vn-cmc",
           "captured_at": "2026-10-24T09:02:00+07:00",
           "step": "connect",
           "error": "connection refused",
           "status_line": null,
           "votes": [
            {
             "location": "vn-cmc",
             "region": null,
             "outcome": "fail",
             "error_kind": "connect",
             "cause_code": null,
             "status_code": null,
             "ip": "203.0.113.10",
             "tls_valid": null,
             "at": "2026-10-24T09:02:00+07:00"
            }
           ]
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/incidents/{incident}/ack": {
   "post": {
    "operationId": "uptime_post_incidents_incident_ack",
    "summary": "Acknowledge an incident",
    "description": "Marks the incident as known to stop repeat alerts: an open incident moves to `ack`; an incident already `ack` or closed is unchanged. Returns the incident.",
    "tags": [
     "Incidents"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-post-incidents-incident-ack"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "incident",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Incident ID (UUID, `id` in the incident list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "7a2d9e44-1c3b-4f6a-8e5d-0b9c2a7f4e21",
          "number": 12,
          "subject_kind": "monitor",
          "subject_id": "3f6c2a10-8b1e-4c5d-9a7f-2e4b6c8d0a11",
          "subject_name": "Website chính",
          "state": "ack",
          "severity": "down",
          "opened_state": "down",
          "tier": "urgent",
          "title": "Website chính không truy cập được",
          "cause_code": null,
          "opened_at": "2026-10-24T09:02:00+07:00",
          "acked_at": "2026-10-24T09:05:00+07:00",
          "resolved_at": null,
          "parent_incident_id": null,
          "children_count": 0,
          "summary": "3/3 vị trí lỗi",
          "evidence": {
           "location": "vn-cmc",
           "captured_at": "2026-10-24T09:02:00+07:00",
           "step": "connect",
           "error": "connection refused",
           "status_line": null,
           "votes": [
            {
             "location": "vn-cmc",
             "region": null,
             "outcome": "fail",
             "error_kind": "connect",
             "cause_code": null,
             "status_code": null,
             "ip": "203.0.113.10",
             "tls_valid": null,
             "at": "2026-10-24T09:02:00+07:00"
            }
           ]
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/channels": {
   "get": {
    "operationId": "uptime_get_channels",
    "summary": "List alert channels",
    "description": "The account's alert channels: type (`kind`), masked target (`target`), verification time (`verified_at`), opt-in (`opted_in_at`: a channel without it receives nothing), why it is off (`disabled_reason`).",
    "tags": [
     "Alert channels"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-get-channels"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Items per page, default 50, at most 100"
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`next_cursor` of the previous page; omit for the first page"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "data": [
           {
            "id": "c41e8b20-6d7f-4a1c-9b3e-5f2a8d0c6e17",
            "kind": "email",
            "name": "Email kỹ thuật",
            "target": "o***@example.com",
            "verified_at": "2026-10-24T10:42:00+07:00",
            "opted_in_at": "2026-10-24T10:42:00+07:00",
            "disabled_reason": null,
            "last_sent_at": null,
            "link_pending": false,
            "route_key": null,
            "created_at": "2026-10-24T10:40:00+07:00"
           }
          ],
          "next_cursor": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "uptime_post_channels",
    "summary": "Create an alert channel",
    "description": "A new channel awaits verification, except an email to the account owner's own verified address. `verification.method` names the next step: `email_code` (code in the email, valid 24 hours), `telegram_link` (open `telegram_url` within 10 minutes), `test_message` (Discord, Slack, webhook: call [verify the channel](/en/docs/api/uptime-post-channels-channel-verify) to send a test message), `zalo_link`, `zalo_otp`. A webhook channel returns `webhook_secret` (`whsec_…`) once only. HTTP 201. A channel type outside the plan's `limits.channels` answers 403 `entitlement_exceeded`.",
    "tags": [
     "Alert channels"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-post-channels"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "kind": {
          "type": "string",
          "description": "`email`, `telegram`, `discord`, `slack`, `webhook` hoặc `zalo`, trong `limits.channels` của gói"
         },
         "name": {
          "type": "string",
          "description": "Tên kênh, 1–100 ký tự"
         },
         "config": {
          "type": "object",
          "description": "`address` cho email; `url` (https) cho Discord, Slack, webhook; Zalo: `consent: true` và `phone` (số di động, xác minh bằng OTP) hoặc bỏ `phone` để liên kết qua OA; Telegram không cần"
         },
         "idempotency_key": {
          "type": "string",
          "description": "8–128 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng body thì không tạo thêm"
         }
        },
        "required": [
         "kind",
         "name"
        ]
       },
       "example": {
        "kind": "email",
        "name": "Email kỹ thuật",
        "config": {
         "address": "ops@example.com"
        },
        "idempotency_key": "kenh-email-ops-0001"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "c41e8b20-6d7f-4a1c-9b3e-5f2a8d0c6e17",
          "kind": "email",
          "name": "Email kỹ thuật",
          "target": "o***@example.com",
          "verified_at": null,
          "opted_in_at": null,
          "disabled_reason": null,
          "last_sent_at": null,
          "link_pending": false,
          "route_key": null,
          "created_at": "2026-10-24T10:40:00+07:00",
          "verification": {
           "method": "email_code",
           "expires_at": "2026-10-25T10:40:00+07:00"
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/channels/{channel}/verify": {
   "post": {
    "operationId": "uptime_post_channels_channel_verify",
    "summary": "Verify an alert channel",
    "description": "Email: send the `code` from the email to verify, omit it to resend the code (at most 5 emails an hour per account, 3 a day per address; beyond that 429 `rate_limited`); a wrong code answers 422 `token_invalid`. Telegram: issues a new deep link. Discord, Slack, webhook: sends a test message and verifies the channel when it gets through. A verified channel is returned unchanged.",
    "tags": [
     "Alert channels"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-post-channels-channel-verify"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "channel",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Alert channel ID (UUID, `id` in the channel list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "code": {
          "type": "string",
          "description": "Kênh email: mã trong thư (4–64 ký tự); bỏ trống để gửi lại mã"
         }
        },
        "required": []
       },
       "example": {
        "code": "482913"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "c41e8b20-6d7f-4a1c-9b3e-5f2a8d0c6e17",
          "kind": "email",
          "name": "Email kỹ thuật",
          "target": "o***@example.com",
          "verified_at": "2026-10-24T10:42:00+07:00",
          "opted_in_at": "2026-10-24T10:42:00+07:00",
          "disabled_reason": null,
          "last_sent_at": null,
          "link_pending": false,
          "route_key": null,
          "created_at": "2026-10-24T10:40:00+07:00"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/channels/{channel}/test": {
   "post": {
    "operationId": "uptime_post_channels_channel_test",
    "summary": "Send a test message",
    "description": "Queues a test message to a verified channel: HTTP 202, no content. An unverified or disabled channel answers 409 `conflict`.",
    "tags": [
     "Alert channels"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-post-channels-channel-test"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "channel",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Alert channel ID (UUID, `id` in the channel list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/uptime/channels/{channel}": {
   "delete": {
    "operationId": "uptime_delete_channels_channel",
    "summary": "Delete an alert channel",
    "description": "Deletes the channel. HTTP 204, no content.",
    "tags": [
     "Alert channels"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/uptime-delete-channels-channel"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "Tino Uptime service ID"
      }
     },
     {
      "name": "channel",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Alert channel ID (UUID, `id` in the channel list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {}
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/overview": {
   "get": {
    "operationId": "builder_get_overview",
    "summary": "TinoPage Builder account overview",
    "description": "Account status (`status`: `active`, `suspended`, `terminated`), the limits in force for the purchased service (`config.effective`: websites of the account; pages, items, custom domains, daily AI uses of each website; `-1` means unlimited), websites in use (`usage`: not deleted including drafts, paused, published) and `login_url`, which opens TinoPage Builder with the Tino account. An account bound to another service answers 404 `SERVICE_NOT_LINKED`.",
    "tags": [
     "Builder account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-get-overview"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "sub": "12345",
          "account_id": 100003,
          "name": "Công ty ABC",
          "email": "lienhe@example.com",
          "phone": "0900000000",
          "status": "active",
          "config": {
           "effective": {
            "sites": 3,
            "pages_per_site": 10,
            "items_per_site": 100,
            "domains_per_site": 2,
            "ai_generations_daily": 20,
            "ai_chat_daily": 100,
            "ai_images_daily": 10
           },
           "overrides": {
            "sites": 3,
            "pages_per_site": 10
           }
          },
          "usage": {
           "sites": 2,
           "sites_paused": 0,
           "sites_published": 1
          },
          "login_url": "https://builder.tino.vn/dang-nhap/tino?return_to=%2Fme",
          "created_at": "2026-10-25T03:00:00Z"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/login": {
   "post": {
    "operationId": "builder_post_login",
    "summary": "One-time sign-in ticket",
    "description": "Returns 201 `{url, expires_at}`: a one-time sign-in link valid for 120 seconds, to the dashboard (`target: me`) or a website's editor (`target: editor`, `site_id`). Open it right away for the service owner; do not store it or send it through another channel. A suspended service still gets a ticket (read-only access); a terminated one answers 403 `ACCOUNT_TERMINATED`.",
    "tags": [
     "Builder account"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-post-login"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "target": {
          "type": "string",
          "description": "`me` (trang quản lý, mặc định) hoặc `editor` (trình sửa website)"
         },
         "site_id": {
          "type": "string",
          "description": "ID website (UUID) cần mở; bỏ trống: website cũ nhất của tài khoản"
         },
         "idempotency_key": {
          "type": "string",
          "description": "8–64 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng nội dung thì nhận lại kết quả lần trước, không làm lại"
         }
        },
        "required": []
       },
       "example": {
        "target": "editor",
        "site_id": "5b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "url": "https://builder.tino.vn/dang-nhap/ve/<ve>",
          "expires_at": "2026-10-26T03:32:00Z"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites": {
   "get": {
    "operationId": "builder_get_sites",
    "summary": "List websites",
    "description": "Websites of the account, oldest first, with `meta` (`page`, `per_page`, `total`, `last_page`). Each has a status (`status`: `draft` not published, `published`), `paused` (paused by the system, `paused_reason: over_limit` when over the website count), the domain it runs on (`host`), a preview link (`preview_url`) and pages, items and domains used against the website's limits.",
    "tags": [
     "Websites"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-get-sites"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Page, default 1"
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Websites per page (all websites currently fit on one page: `meta.last_page` is 1)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": "5b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
           "name": "Tiệm bánh Hoa Mai",
           "slug": "tiem-banh-hoa-mai",
           "status": "published",
           "paused": false,
           "paused_reason": null,
           "host": "example.vn",
           "preview_url": "https://builder.tino.vn/tiem-banh-hoa-mai",
           "pages": {
            "used": 3,
            "limit": 10
           },
           "items": {
            "used": 12,
            "limit": 100
           },
           "domains": {
            "used": 1,
            "limit": 2
           },
           "created_at": "2026-10-26T02:10:00Z",
           "updated_at": "2026-10-26T03:20:00Z"
          }
         ],
         "meta": {
          "page": 1,
          "per_page": 1,
          "total": 1,
          "last_page": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "builder_post_sites",
    "summary": "Create a website with AI",
    "description": "JSON body `{intake}`: the AI picks a template and writes the content from the business details. HTTP 202: creation runs in the background for 1–5 minutes; poll [Website creation progress](/en/docs/api/builder-get-site-creation) until `state` is `done` (`site_id` is the new website) or `failed`. One creation per account at a time: 409 `CREATION_IN_PROGRESS`; no websites left: 409 `LIMIT_EXCEEDED` (`details.key: sites`); missing or invalid fields: 422 `VALIDATION_FAILED` per `intake.<field>`; AI paused: 503 `AI_UNAVAILABLE`.",
    "tags": [
     "Websites"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-post-sites"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "intake": {
          "type": "object",
          "description": "Thông tin cơ sở kinh doanh để AI chọn mẫu và viết nội dung: `business_name`, `industry`, `phone` bắt buộc; `address`, `city`, `services`, `hours`, `zalo`, `email` tuỳ chọn; độ dài tối đa ở [Bắt đầu với TinoPage Builder](/docs/builder-start#tao-website-bang-ai)"
         },
         "idempotency_key": {
          "type": "string",
          "description": "8–64 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng nội dung thì nhận lại kết quả lần trước, không làm lại"
         }
        },
        "required": [
         "intake"
        ]
       },
       "example": {
        "intake": {
         "business_name": "Tiệm bánh Hoa Mai",
         "industry": "tiệm bánh",
         "phone": "0900000000",
         "city": "Thành phố Hồ Chí Minh",
         "services": "bánh sinh nhật, bánh mì"
        },
        "idempotency_key": "tao-website-0001"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "state": "running",
          "site_id": null,
          "message": null,
          "started_at": "2026-10-26T02:00:00Z",
          "finished_at": null
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites/{site}": {
   "get": {
    "operationId": "builder_get_sites_site",
    "summary": "Website details",
    "description": "One website as in the list, plus `todo`: contacts not yet called back (`leads_new`) and orders not yet confirmed (`orders_new`). A website outside the account answers 404 `RESOURCE_NOT_FOUND`.",
    "tags": [
     "Websites"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-get-sites-site"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "5b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
          "name": "Tiệm bánh Hoa Mai",
          "slug": "tiem-banh-hoa-mai",
          "status": "published",
          "paused": false,
          "paused_reason": null,
          "host": "example.vn",
          "preview_url": "https://builder.tino.vn/tiem-banh-hoa-mai",
          "pages": {
           "used": 3,
           "limit": 10
          },
          "items": {
           "used": 12,
           "limit": 100
          },
          "domains": {
           "used": 1,
           "limit": 2
          },
          "created_at": "2026-10-26T02:10:00Z",
          "updated_at": "2026-10-26T03:20:00Z",
          "todo": {
           "leads_new": 2,
           "orders_new": 1
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "delete": {
    "operationId": "builder_delete_sites_site",
    "summary": "Delete a website",
    "description": "Deletes the website (to the trash: Tino can restore it on request through support), removes its custom domains and frees one of the account's websites. Returns `{\"deleted\": true}`. Send `idempotency_key` in the query.",
    "tags": [
     "Websites"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-delete-sites-site"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     },
     {
      "name": "idempotency_key",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "8–64 characters `A-Za-z0-9._:-`: resending the same key and content returns the earlier result instead of running again"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "deleted": true
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/site-creation": {
   "get": {
    "operationId": "builder_get_site_creation",
    "summary": "Website creation progress",
    "description": "The account's latest website creation: `state` is `idle` (none yet, or the result is over 1 hour old), `running`, `done` (`site_id` is the new website) or `failed` (`message` is the reason in Vietnamese); `started_at`, `finished_at`. It may also carry `step` (the running step) and `mode`. A created website stays in the list after the creation goes back to `idle`.",
    "tags": [
     "Websites"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-get-site-creation"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "state": "done",
          "site_id": "5b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
          "message": null,
          "started_at": "2026-10-26T02:00:00Z",
          "finished_at": "2026-10-26T02:02:40Z"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites/{site}/publish": {
   "post": {
    "operationId": "builder_post_sites_site_publish",
    "summary": "Publish a website",
    "description": "Publishes the website's latest version, which also reopens a paused website. Returns the website. A website the system paused because the account is over its website count answers 409 `SITE_PAUSED`: delete another website or raise the service's website count.",
    "tags": [
     "Websites"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-post-sites-site-publish"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "idempotency_key": {
          "type": "string",
          "description": "8–64 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng nội dung thì nhận lại kết quả lần trước, không làm lại"
         }
        },
        "required": []
       },
       "example": {
        "idempotency_key": "dang-website-0001"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "5b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
          "name": "Tiệm bánh Hoa Mai",
          "slug": "tiem-banh-hoa-mai",
          "status": "published",
          "paused": false,
          "paused_reason": null,
          "host": "example.vn",
          "preview_url": "https://builder.tino.vn/tiem-banh-hoa-mai",
          "pages": {
           "used": 3,
           "limit": 10
          },
          "items": {
           "used": 12,
           "limit": 100
          },
          "domains": {
           "used": 1,
           "limit": 2
          },
          "created_at": "2026-10-26T02:10:00Z",
          "updated_at": "2026-10-26T03:20:00Z"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites/{site}/unpublish": {
   "post": {
    "operationId": "builder_post_sites_site_unpublish",
    "summary": "Pause a website",
    "description": "Takes the website off the web with its content kept (`status` back to `draft`). Returns the website. Publish it again with [Publish a website](/en/docs/api/builder-post-sites-site-publish).",
    "tags": [
     "Websites"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-post-sites-site-unpublish"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "idempotency_key": {
          "type": "string",
          "description": "8–64 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng nội dung thì nhận lại kết quả lần trước, không làm lại"
         }
        },
        "required": []
       },
       "example": {
        "idempotency_key": "tam-ngung-0001"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "id": "5b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
          "name": "Tiệm bánh Hoa Mai",
          "slug": "tiem-banh-hoa-mai",
          "status": "draft",
          "paused": false,
          "paused_reason": null,
          "host": "example.vn",
          "preview_url": "https://builder.tino.vn/tiem-banh-hoa-mai",
          "pages": {
           "used": 3,
           "limit": 10
          },
          "items": {
           "used": 12,
           "limit": 100
          },
          "domains": {
           "used": 1,
           "limit": 2
          },
          "created_at": "2026-10-26T02:10:00Z",
          "updated_at": "2026-10-26T03:20:00Z"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites/{site}/domains": {
   "get": {
    "operationId": "builder_get_sites_site_domains",
    "summary": "Custom domains of a website",
    "description": "`items`: domains added, each with a status (`status`: `pending` waiting for DNS, `active`), HTTPS certificate (`ssl_status`: `pending`, `active`, `error`), records to set (`dns`: CNAME to `dns_target`, TXT `_tino-verify` proving ownership), and the latest check (`cname_ok`, `txt_ok`, `error`, `checked_at`); `limit` (domains per website, `-1` means unlimited) and `used`.",
    "tags": [
     "Custom domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-get-sites-site-domains"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "items": [
           {
            "hostname": "example.vn",
            "status": "active",
            "ssl_status": "active",
            "txt_ok": true,
            "cname_ok": true,
            "dns": [
             {
              "type": "CNAME",
              "name": "@",
              "value": "dns.tino.page"
             },
             {
              "type": "CNAME",
              "name": "www",
              "value": "dns.tino.page"
             },
             {
              "type": "TXT",
              "name": "_tino-verify",
              "value": "tino-site-verify=8f3a2c1d9e7b4a6c0d5e1f2a3b4c5d6e"
             }
            ],
            "error": "",
            "checked_at": "2026-10-26T03:00:00Z",
            "url": "https://example.vn",
            "owner_verified": false,
            "check_count": 0
           },
           {
            "hostname": "banhang.example.vn",
            "status": "pending",
            "ssl_status": "pending",
            "txt_ok": false,
            "cname_ok": false,
            "dns": [
             {
              "type": "CNAME",
              "name": "banhang",
              "value": "dns.tino.page"
             },
             {
              "type": "TXT",
              "name": "_tino-verify.banhang",
              "value": "tino-site-verify=4b6d0e2a7c914f3e8a5b1c2d9e0f7a6b"
             }
            ],
            "error": "thiếu bản ghi TXT _tino-verify; CNAME chưa trỏ về dns.tino.page",
            "checked_at": "2026-10-26T03:30:00Z",
            "url": "https://banhang.example.vn",
            "owner_verified": false,
            "check_count": 1,
            "next_check_at": "2026-10-26T03:35:00Z"
           }
          ],
          "dns_target": "dns.tino.page",
          "limit": 2,
          "used": 2
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   },
   "post": {
    "operationId": "builder_post_sites_site_domains",
    "summary": "Add a custom domain",
    "description": "Adds a domain to the website: HTTP 201, the domain is `pending` with the DNS records the customer must set (`dns`). For an apex domain, `dns` also has a CNAME for `www`. An unpublished website answers 409 `SITE_NOT_PUBLISHED`; no domains left: 409 `LIMIT_EXCEEDED` (`details.key: domains_per_site`); domain in use by another website: 409 `DOMAIN_TAKEN`; not a domain: 422 `VALIDATION_FAILED`.",
    "tags": [
     "Custom domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-post-sites-site-domains"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "hostname": {
          "type": "string",
          "description": "Tên miền cần gắn (1–253 ký tự), vd `example.vn` hoặc `banhang.example.vn`; TinoPage Builder tự bỏ `https://`, đường dẫn, chữ hoa"
         },
         "idempotency_key": {
          "type": "string",
          "description": "8–64 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng nội dung thì nhận lại kết quả lần trước, không làm lại"
         }
        },
        "required": [
         "hostname"
        ]
       },
       "example": {
        "hostname": "banhang.example.vn",
        "idempotency_key": "them-ten-mien-0001"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "hostname": "banhang.example.vn",
          "status": "pending",
          "ssl_status": "pending",
          "txt_ok": false,
          "cname_ok": false,
          "dns": [
           {
            "type": "CNAME",
            "name": "banhang",
            "value": "dns.tino.page"
           },
           {
            "type": "TXT",
            "name": "_tino-verify.banhang",
            "value": "tino-site-verify=4b6d0e2a7c914f3e8a5b1c2d9e0f7a6b"
           }
          ],
          "error": "",
          "checked_at": "0001-01-01T00:00:00Z",
          "url": "https://banhang.example.vn",
          "owner_verified": false,
          "check_count": 0
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites/{site}/domains/{hostname}/verify": {
   "post": {
    "operationId": "builder_post_sites_site_domains_hostname_verify",
    "summary": "Check DNS again",
    "description": "Checks the domain's DNS records now (up to about 12 seconds) and returns the domain after the check. With both CNAME and TXT in place `status` turns `active` and HTTPS is issued automatically; otherwise `error` says what is missing. TinoPage Builder also rechecks `pending` domains on a schedule (`next_check_at`).",
    "tags": [
     "Custom domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-post-sites-site-domains-hostname-verify"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     },
     {
      "name": "hostname",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Custom domain in lower case (`hostname` in the domain list)"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "idempotency_key": {
          "type": "string",
          "description": "8–64 ký tự `A-Za-z0-9._:-`: gửi lại cùng khoá và cùng nội dung thì nhận lại kết quả lần trước, không làm lại"
         }
        },
        "required": []
       },
       "example": {
        "idempotency_key": "kiem-dns-0001"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "hostname": "banhang.example.vn",
          "status": "pending",
          "ssl_status": "pending",
          "txt_ok": false,
          "cname_ok": false,
          "dns": [
           {
            "type": "CNAME",
            "name": "banhang",
            "value": "dns.tino.page"
           },
           {
            "type": "TXT",
            "name": "_tino-verify.banhang",
            "value": "tino-site-verify=4b6d0e2a7c914f3e8a5b1c2d9e0f7a6b"
           }
          ],
          "error": "thiếu bản ghi TXT _tino-verify; CNAME chưa trỏ về dns.tino.page",
          "checked_at": "2026-10-26T03:30:00Z",
          "url": "https://banhang.example.vn",
          "owner_verified": false,
          "check_count": 1,
          "next_check_at": "2026-10-26T03:35:00Z"
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites/{site}/domains/{hostname}": {
   "delete": {
    "operationId": "builder_delete_sites_site_domains_hostname",
    "summary": "Remove a custom domain",
    "description": "Removes the domain from the website. Returns `{\"removed\": true}`. Send `idempotency_key` in the query.",
    "tags": [
     "Custom domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-delete-sites-site-domains-hostname"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     },
     {
      "name": "hostname",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Custom domain in lower case (`hostname` in the domain list)"
      }
     },
     {
      "name": "idempotency_key",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "8–64 characters `A-Za-z0-9._:-`: resending the same key and content returns the earlier result instead of running again"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": {
          "removed": true
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/service/{id}/builder/sites/{site}/leads": {
   "get": {
    "operationId": "builder_get_sites_site_leads",
    "summary": "Contacts and orders",
    "description": "Read only: contacts (`kind=lead`) or orders (`kind=order`) left on the website, newest first, filtered by `status`, paged with `page`, `per_page` (at most 50) and `meta`. A contact has `name`, `phone`, the form content (`payload`, keys depend on the website's form) and `source_page`; an order has its code, items, shipping fee, total (`null` when the website shows no price), payment method and status. Handle contacts and orders in TinoPage Builder ([sign-in ticket](/en/docs/api/builder-post-login)).",
    "tags": [
     "Contacts & orders"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/builder-get-sites-site-leads"
    },
    "security": [
     {
      "session": []
     }
    ],
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "description": "TinoPage Builder service ID"
      }
     },
     {
      "name": "site",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Website ID (UUID, `id` in the website list)"
      }
     },
     {
      "name": "kind",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "`lead` (contacts, default) or `order` (orders)"
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "description": "Filter by status: `moi`, `da_lien_he`, `xac_nhan`, `dang_giao`, `hoan_tat`, `huy`; omit for all"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Page, default 1"
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "description": "Items per page, default 20, at most 50"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "data": [
          {
           "id": "9c4d2e10-7b3a-4f8e-a1d6-2e5f8c0b7a34",
           "code": "DH0012",
           "name": "Nguyễn Văn A",
           "phone": "0900000000",
           "address": "12 Lê Lợi, phường Bến Thành",
           "note": "Giao trước 17 giờ",
           "items": [
            {
             "name": "Bánh kem dâu",
             "option": "20 cm",
             "qty": 1,
             "subtotal": 350000
            }
           ],
           "shipping": 30000,
           "total": 380000,
           "payment": "COD",
           "status": "xac_nhan",
           "status_label": "Đã xác nhận",
           "created_at": "2026-10-26T01:45:00Z",
           "sheet_error": ""
          }
         ],
         "meta": {
          "page": 1,
          "per_page": 20,
          "total": 1,
          "last_page": 1
         }
        }
       }
      }
     },
     "401": {
      "description": "invalid_token"
     },
     "403": {
      "description": "insufficient_scope, ip_not_allowed (token cá nhân), ipnotallowed"
     }
    }
   }
  },
  "/whois/{domain}": {
   "get": {
    "operationId": "get_whois_domain",
    "summary": "Domain whois lookup",
    "description": "Looks up the whois of a domain with no token (call `https://api.tino.vn` directly, not through the `/v1` gateway). It always answers HTTP 200 with `success: true`; read the result in this order:\n\n- `error` present (e.g. `incorrect_tld`: invalid extension or one that cannot be looked up): ignore `available`; the answer still says `available: true`.\n- `raw` is `Rate limit exceeded`: too many lookups; `available: false` then does not mean the domain is taken. Wait and look it up again.\n- `domain` is an extension Tino sells (e.g. `vn`): only `success`, `domain`, `available: false`.\n- `available: true`, `status: ok`, `whois: []`: no whois data for the domain (`raw` is the raw text or `Domain not found`).\n- `available: false` with a `whois` object: the domain is taken. Fields appear when the registry returns them: `domain`, `registrar`, `createDate`, `expiredDate`, `updatedDate`, `registrantName`, `registrantOrg`, `nameservers`, `Dnssec`, `status`, `WhoisServer`, `DomainReserved`. Dates keep the registry's format (e.g. `+07:00` for `.vn`, `Z` for `.com`).\n\n`raw` is the raw whois text: lines end with `<br />` and special characters are HTML-encoded.",
    "tags": [
     "Domains"
    ],
    "externalDocs": {
     "url": "https://developers.tino.vn/en/docs/api/get-whois-domain"
    },
    "security": [],
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "description": "Domain to look up (e.g. `tino.vn`), or an extension (e.g. `vn`)"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "The route's answer (business errors usually also come as HTTP 200 with `error`)",
      "content": {
       "application/json": {
        "example": {
         "success": true,
         "domain": "tino.vn",
         "available": false,
         "status": "",
         "whois": {
          "domain": "tino.vn",
          "registrar": "Công ty Cổ phần Tập đoàn Tino",
          "createDate": "2022-02-02T16:32:35+07:00",
          "expiredDate": "2035-02-02T16:32:35+07:00",
          "registrantName": "CÔNG TY CỔ PHẦN TẬP ĐOÀN TINO",
          "nameservers": [
           "ns1.tino.vn",
           "ns2.tino.vn"
          ],
          "Dnssec": "unsigned",
          "status": [
           "clientDeleteProhibited",
           "clientTransferProhibited",
           "serverUpdateProhibited",
           "serverDeleteProhibited",
           "serverTransferProhibited"
          ]
         },
         "raw": "Dnssec: unsigned<br />Domain Name: tino.vn<br />Registry Expiry Date: 2035-02-02T16:32:35+07:00<br />…"
        }
       }
      }
     }
    }
   }
  }
 }
}