---
title: "Moving from the Vitu Classic API to the new Vitu API"
description: "The API functionality stays the same. What changes is how you authenticate and which domain you call."
url: "https://developer-stage.vitu.com/migration-guides/classic-vitu"
image: "https://developer-stage.vitu.com/_og/d/c_Ocean.takumi,title_Moving+from+the+Vitu+Classic+API+to+the+new+Vitu+API,description_The+API+functionality+stays+the+same.+What+changes+is+how+you+authenticate+and+which+domain+you+call.,props_eyJ0aGVtZSI6eyJtb2RlIjoiZGFyayIsImNvbG9ycyI6eyJwcmltYXJ5IjoiIzE3M2M0ZCJ9fX0,p_Ii9taWdyYXRpb24tZ3VpZGVzL2NsYXNzaWMtdml0dSI,s_Ccu075dAcmr25-M1.png"
---

[Back to Migration Guides](https://developer-stage.vitu.com/migration-guides)

# Vitu Classic to New API Migration Guide

## [What's Changing & When](#whats-changing-when)

API functionality stays the same. Only how you authenticate and which domain you call changes.

In total, four settings change, in both stage and production. Every endpoint path, request payload, and response shape stays exactly as it is today.

Changes

-   Auth URL
-   Client credentials
-   Scope
-   API domain

Stays the Same

-   Every endpoint path
-   Request payloads
-   Response shapes

All customers migrated by December 31, 2026

Both the Classic API and the new API are available in the meantime, so you can migrate stage, verify, and schedule production on your own release calendar.

## [Update Settings](#update-settings)

Start from the setup process in the [Quick Start](https://developer-stage.vitu.com/#quick-start), then update the four values below. Do this in stage first, confirm, then repeat the same swaps in production.

Stage

Production

| Setting            | From (Classic)                                                                   | To (new API)                                                         |
| :----------------- | :------------------------------------------------------------------------------- | :------------------------------------------------------------------- |
| Auth URL           | https://vitu-stage.us.auth0.com/oauth/token?audience=https%3A%2F%2Fvitu.com%2Fnational-public-api | https://auth.stage.vitu.com/realms/api/protocol/openid-connect/token |
| API domain         | https://proxy-stage-developer.vitu.com                                           | https://api-stage.vitu.com                                           |
| Client credentials | Existing stage clientId and secret                                               | New stage clientId and secret, requested in the developer portal     |
| Scope              | Not used — access was scoped by the audience parameter                           | oneapi:access                                                        |

| Setting            | From (Classic)                                                                   | To (new API)                                                          |
| :----------------- | :------------------------------------------------------------------------------- | :-------------------------------------------------------------------- |
| Auth URL           | https://auth.vitu.com/oauth/token?audience=https%3A%2F%2Fvitu.com%2Fnational-public-api | https://auth.secure.vitu.com/realms/api/protocol/openid-connect/token |
| API domain         | https://proxy-www-developer.vitu.com                                             | https://api.vitu.com                                                  |
| Client credentials | Existing production clientId and secret                                          | New production clientId and secret, requested in the developer portal |
| Scope              | Not used — access was scoped by the audience parameter                           | oneapi:access                                                         |

Note the shape of the new auth URL: the `audience` query parameter is gone. Token requests are now standard OAuth 2.0 client-credentials calls against a Keycloak endpoint, and they carry the scope `oneapi:access` in the request body.

## [Migration Checklist](#migration-checklist)

1. Complete the Quick Start Setup

Complete the Quick Start Setup

Follow the setup process in the [new developer portal Quick Start](https://developer-stage.vitu.com/#quick-start) to register your organization and get access to the portal.

2. Request New Client Credentials

Request New Client Credentials

On the developer portal's [Key Management](https://api-identity-pp.service.vitu.com/forms/credentials) page, request credentials for stage and for production. These are new values; your Classic clientId and secret will not work against the new auth URL.

3. Update the Auth URL and Scope in your Configuration

Update the Auth URL and Scope in your Configuration

Point your token request at the new endpoint, drop the `audience` parameter, and send `scope=oneapi:access`.

4. Update the Base Domain

Update the Base Domain

Swap the domain your client points at. Everything after the domain — paths, query strings, bodies, headers — stays exactly as it is today.

5. Verify in Stage

Verify in Stage

Request a token, then run one read call and one write call you already rely on. Compare the responses with what Classic returns.

6. Promote to Production

Promote to Production

Apply the same four changes with your production credentials and domain, and retire the Classic values from your configuration.

## [Requesting a Token](#requesting-a-token)

Stage values shown. For production, use `https://auth.secure.vitu.com/realms/api/protocol/openid-connect/token`. The response is a standard bearer token; send it as `Authorization: Bearer <access_token>` exactly as you do today.

cURL

C# / .NET

Java

Node.js

Python

```bash
curl -X POST https://auth.stage.vitu.com/realms/api/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$VITU_CLIENT_ID" \
  -d "client_secret=$VITU_CLIENT_SECRET" \
  -d "scope=oneapi:access"
```

```csharp
var http = new HttpClient();
var form = new FormUrlEncodedContent(new Dictionary<string, string>
{
    ["grant_type"] = "client_credentials",
    ["client_id"] = clientId,
    ["client_secret"] = clientSecret,
    ["scope"] = "oneapi:access"
});

var res = await http.PostAsync(
    "https://auth.stage.vitu.com/realms/api/protocol/openid-connect/token", form);
res.EnsureSuccessStatusCode();
var token = JsonDocument.Parse(await res.Content.ReadAsStringAsync())
    .RootElement.GetProperty("access_token").GetString();
```

```java
var body = "grant_type=client_credentials"
    + "&client_id=" + URLEncoder.encode(clientId, UTF_8)
    + "&client_secret=" + URLEncoder.encode(clientSecret, UTF_8)
    + "&scope=" + URLEncoder.encode("oneapi:access", UTF_8);

var request = HttpRequest.newBuilder()
    .uri(URI.create("https://auth.stage.vitu.com/realms/api/protocol/openid-connect/token"))
    .header("Content-Type", "application/x-www-form-urlencoded")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

var response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
```

```javascript
const res = await fetch(
  "https://auth.stage.vitu.com/realms/api/protocol/openid-connect/token",
  {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "client_credentials",
      client_id: process.env.VITU_CLIENT_ID,
      client_secret: process.env.VITU_CLIENT_SECRET,
      scope: "oneapi:access",
    }),
  }
);

const { access_token } = await res.json();
```

```python
import os, requests

res = requests.post(
    "https://auth.stage.vitu.com/realms/api/protocol/openid-connect/token",
    data={
        "grant_type": "client_credentials",
        "client_id": os.environ["VITU_CLIENT_ID"],
        "client_secret": os.environ["VITU_CLIENT_SECRET"],
        "scope": "oneapi:access",
    },
)
res.raise_for_status()
token = res.json()["access_token"]
```

## [Failures](#failures)

401 `invalid_client`

The credentials are Classic credentials, or stage credentials sent to production. Confirm the pair came from the key management page for the environment you are calling.

400 `invalid_request`

Usually a leftover `audience` parameter, or credentials sent as JSON. The new endpoint expects form-encoded fields.

`invalid_scope`

The scope is missing or misspelled. It is exactly `oneapi:access`, sent as a `scope` field in the form body.

404 on a known path

The base domain still contains `proxy-`, or the new domain was concatenated with a path that already included the old host.

401 on API calls

A token from the Classic auth URL will not authenticate against the new domain. Both values have to move together.

TLS or DNS errors

If your network allow-lists outbound hosts, add the new auth and API domains before you cut over.

## [Getting Help](#getting-help)

Credentials, portal access, and environment questions all start in the [developer portal](https://developer-stage.vitu.com/). If a call behaves differently on the new domain than it does on Classic, contact your Vitu account manager with the request, the response, and the environment, and we will trace it.