# Calling the Tino API

Customer apps and software call the Tino API on the customer's behalf through the gateway `https://api.tino.vn/v1/<route>`: each route runs the UserAPI route of the same name with the customer's account, within the scopes of the token. Request bodies and responses keep the UserAPI format (see [Personal data](#personal-data)). AI assistants call the same routes as tools through the [MCP server](/en/docs/mcp).

Updated: 2026-10-21. Routes, scopes, names and parameters match the live gateway; sample responses are real answers with personal data masked.

## Authentication

Every route needs the header `Authorization: Bearer <token>`, with one of two token types:

| Token | Prefix | Where it comes from | Can call |
| --- | --- | --- | --- |
| App token (access token) | `tinoat_` | [Sign in with Tino](/en/docs/oauth): the customer agrees to grant scopes to the app | routes in the scopes the customer approved; never `domains:owner` |
| Personal API token | `tinopat_` | [created by the customer](/en/docs/personal-tokens) at `https://auth.tino.vn/en/me/security`, in the API tokens section | routes in the scopes the customer chose, including `domains:owner` (IP restriction required); only from IPs in the list, if one is set |

```bash
curl https://api.tino.vn/v1/details -H "Authorization: Bearer $TINO_TOKEN"
```

Each route page lists the required scope and the token types that can call the route.

Exception: public routes need no token and are called on `https://api.tino.vn` directly (no `/v1`); currently [Domain whois lookup](/en/docs/api/get-whois-domain) (`GET /whois/<domain>`).

## Sending parameters

- Path parameters: the docs write `@id`, `@vmid`…; replace them with real values, for example `GET /v1/service/12345`.
- `GET`, `DELETE`: parameters go in the query string.
- `POST`, `PUT`: JSON body with `Content-Type: application/json`. The gateway also reads the query string and form bodies (`application/x-www-form-urlencoded`).
- Pagination (on list routes that support it): `page` starts at 0, `perpage` is the number of rows per page; the response has `page.current`, `page.total`.
- Filtering and sorting: `filter[<key>]=<value>`, `orderby=<field>|DESC` or `|ASC`.

## Personal data

The `/v1` gateway returns the route's response unchanged, including identity data of the account, contacts and domain registrants (ID document numbers, date of birth, phone number, address, tax code): a token that can call it belongs to the account owner or was authorized by the account owner. Keep tokens like passwords; do not log these fields, and do not store them when the app does not need them.

The [MCP server](/en/docs/mcp), by contrast, filters out identity fields before sending results to the AI assistant.

## Errors

The gateway rejects requests with the body `{"error": ["<code>"]}`; 401 errors and `insufficient_scope` also carry the header `WWW-Authenticate: Bearer error="<code>"` (with `scope` and `resource_metadata` for MCP clients).

| HTTP | `error` | Cause | Fix |
| --- | --- | --- | --- |
| 401 | `invalid_token` | the token is wrong, expired or revoked | apps refresh the token; for personal tokens, create a new token |
| 403 | `insufficient_scope` | the token lacks the route's scope, or the route is not in the gateway | request more scopes (apps) or create a token with more scopes (personal tokens) |
| 403 | `ip_not_allowed` | a personal API token was used from an IP outside its allowed list | call from a listed IP, or create a token with a new IP list |
| 403 | `ipnotallowed` | the calling IP is blocked by Tino | contact Tino |

Business errors of each route (for example, a service that does not exist) keep the UserAPI response, usually HTTP 200 with `{"error": ["<code>"]}`; successful actions usually return `{"info": ["<code>"]}`.

## Route list

Each route has its own page: parameters, cURL, JavaScript and PHP examples, sample response; the index by product is at [API Reference](/en/docs/reference), the machine-readable version at [/openapi.json](/en/openapi.json). Markdown for LLMs: add `.md` to the page path (for example `/en/docs/api/get-details.md`); everything is in [/llms-full.txt](/en/llms-full.txt).
