# API overview

> Learn how the ITVA GraphQL API works, where to find your instance's endpoint, and how the schema is organized.

Section: API  
Source: https://www.itva.com/docs/api/api-overview  
Last updated: 2026-11-03

ITVA has a GraphQL API. The ITVA portal uses this same API, so you can use it to read your data and automate the changes you make in the portal.

## How the API works

You send every request to one endpoint, as an HTTP POST with a JSON body. The body has a `query` string and, if the query needs them, a `variables` object.

ITVA answers with JSON. The `data` object has the fields you asked for. If something goes wrong, the response also has an `errors` array.

Each request must include an API key. To create one, see [Authenticate to the API](https://www.itva.com/docs/api/authenticate-to-the-api).

## Your API endpoint

Each ITVA instance has its own endpoint. Take the address you use to open the portal, and add `/graphql/` to it:

```
https://<INSTANCE_NAME>.itva.com/graphql/
```

Replace `<INSTANCE_NAME>` with the name in your portal address.

Include the slash at the end. If you send a POST to `/graphql` without it, ITVA answers with a redirect, not with the result of your query.

## Explore the schema

The API supports introspection. GraphQL clients and code generators can read the full schema from your endpoint, then show the available fields and complete them for you.

You can also open your endpoint in a browser. If you are signed in to the portal in the same browser, the page shows GraphiQL. GraphiQL is an editor where you can browse the schema and run queries.

**Caution:** GraphiQL runs each request as you, with your access. A mutation that you run there changes your real data.

## How the schema is organized

The schema has two root types. `Query` has the fields that read data. `Mutation` has the fields that change data. The API has no subscriptions.

Most item types use the same names for the same operations. This table uses devices as the example.

| Operation | Field | Returns |
| --- | --- | --- |
| Get one item | device(id) | The item |
| List items | devices(filters) | A list of items |
| List one page of items | devicesPaginated(filters, order, pagination) | totalCount, pageInfo, and results |
| Create an item | deviceCreate(input) | DeviceResponse: error and device |
| Change an item | deviceUpdate(id, input) | DeviceResponse: error and device |
| Archive an item | deviceArchive(id) | The item |

_Some item types have a Delete mutation, such as apiKeyDelete, in place of Archive._

### Filters and order

List fields take a `filters` argument. Each item type has its own filter input, for example `DeviceFilter`. You can combine conditions with `AND`, `OR`, and `NOT`.

Paginated fields also take an `order` argument. An order input takes one field at a time, with a value such as `ASC` or `DESC`.

### Pagination

Paginated fields take `pagination: { offset, limit }`. ITVA returns at most 500 items for each page. If you ask for more, ITVA returns 500. To get the next page, add the limit to the offset.

This query finds devices that match the text "core", sorted by name, and returns the first 100:

```
query {
  devicesPaginated(
    filters: { query: "core" }
    order: { name: ASC }
    pagination: { offset: 0, limit: 100 }
  ) {
    totalCount
    results {
      id
      name
      managementIp
      vendor
      reachable
    }
  }
}
```

### Mutation results

Most create and update mutations return a response object with an `error` field and the item. If ITVA cannot save the change, `error` has the reason and the item is null. The HTTP status is still 200, so always request `error` and check it.

### Custom scalars

The schema adds these scalar types to the standard GraphQL types:

| Scalar | Format |
| --- | --- |
| Duration | An ISO 8601 duration string, for example PT5M |
| BPS | Bits per second, as a string of digits |
| BigInt | A large integer, as a string of digits |
| IPAddress | An IPv4 or IPv6 address |
| Email | An email address, for example user@example.com |
| Phone | A phone number in international format, for example +15555555555 |

## Errors

ITVA puts a code in `extensions.code` for some errors:

- `UNAUTHENTICATED`: the request has no valid API key.
- `UNAUTHORIZED`: the field is for administrators only, and the API key does not have administrator access.

If the API key cannot do an action on an item, the error message names the action and the item type. For example: `You are not authorized to update the 'Device' resource.`

If you ask for one item that does not exist, or that the API key cannot see, the message is `You are unauthorized to access this resource.` To learn what an API key can see, see [Restrict API access](https://www.itva.com/docs/api/restrict-api-access).
