# Migrate from v1 to v2

The Databox API v1 covered a focused set of operations: discovering accounts, managing data sources, and creating and ingesting into datasets. v2 keeps all of that functionality but reshapes the request and response formats, and adds a much larger surface area — billing, accounts, connections, Databoards, integrations, metrics, user and profile management, and significantly deeper control over data sources and datasets.

This guide covers everything you need to move an existing v1 integration to v2: the breaking changes to account for, what's new, and a full endpoint-by-endpoint mapping.

v1 is still available
v1 continues to run at its existing base URL. You don't need to migrate immediately, but new functionality is only being added to v2, so any integration that needs the capabilities below will need to move.

## What's new in v2

v1 exposed four resources: Accounts, Auth, Data Sources, and Datasets. v2 organizes the API into twelve:

| Resource | What you can do |
|  --- | --- |
| Accounts | Create, retrieve, update, and delete accounts. |
| Auth | Validate API credentials and confirm access to the API. |
| Billing | Retrieve billing details and invoices for the organization. |
| Connections | Manage integration connections and their permissions. |
| Data Sources | Manage data sources, sync settings, time zones, permissions, and stored data. |
| Databoards | Retrieve Databoards and information about their metrics. |
| Datasets | Manage datasets, data ingestion, schemas, metadata, transformations, sync, permissions, verification, and stored data. |
| Integrations | Retrieve available integrations and their details. |
| Metrics | Manage metrics and retrieve metric data, dimensions, drilldowns, usages, and verification details. |
| Organization | Manage organization details, retrieve organization usage and supported time zones, and view the organization's activity log. |
| Profile | Retrieve and update the profile of the authenticated user. |
| Users | Create, retrieve, update, and delete users. |


Within the resources carried over from v1, Data Sources and Datasets both gained substantial new capabilities, including permissions management, configurable sync frequency, time zone updates, column metadata, calculated-column modifications, lineage, and verification status.

## Breaking changes

### 1. New base path

Every path moves from `/v1/...` to `/v2/...`:

```diff
- https://api.databox.com/v1/datasets/{datasetId}/data
+ https://api.databox.com/v2/datasets/{id}/data
```

### 2. Every response body now nests its payload under `data`

In v1, a successful response put the resource directly at the top level, next to `requestId` and `status`. In v2, it's nested under a `data` field instead. Error responses are unchanged — `requestId`, `status`, and `errors` remain at the top level.

```diff
  {
    "requestId": "b0eac937-c25c-47a5-bb7e-552f6b860458",
    "status": "success",
-   "title": "Transactions",
-   "id": "4e1219d8-7fa8-44b7-96c6-a8f2a9cfb0bf",
-   "created": "2025-10-01T12:00:00.000000Z"
+   "data": {
+     "name": "Transactions",
+     "id": "4e1219d8-7fa8-44b7-96c6-a8f2a9cfb0bf",
+     "createdAt": "2025-10-01T12:00:00.000000Z"
+   }
  }
```

Any client code that reads a resource straight off the response root needs to read it from `response.data` instead.

### 3. List responses use a generic `items` array instead of a resource-named key

v1 named the array after the resource (`accounts`, `dataSources`, `datasets`, `ingestions`, ...). v2 always calls it `items`, nested under `data`, alongside `pagination`:

```diff
  {
    "requestId": "b0eac937-c25c-47a5-bb7e-552f6b860458",
    "status": "success",
-   "dataSources": [ { "id": 4754489, "title": "ERP System", ... } ]
+   "data": {
+     "items": [ { "id": 4754489, "name": "ERP System", ... } ],
+     "pagination": { "page": 0, "pageSize": 25, "totalItems": 1 }
+   }
  }
```

### 4. Pagination is zero-indexed, and the default page size is smaller

Silent breaking change
If your v1 client requests `page=1` expecting the first page, v2 will return the **second** page instead — page numbering now starts at `0`. Update any hardcoded page counters.

| Parameter | v1 | v2 |
|  --- | --- | --- |
| `page` | 1-indexed, defaults to `1` | 0-indexed, defaults to `0` |
| `pageSize` | Defaults to `100` | Defaults to `25`, maximum `100` |


### 5. Path parameters are now named `id` generically

v1's path templates named the identifier after the resource — `{accountId}`, `{dataSourceId}`, `{datasetId}`. v2 uses `{id}` for all of them. The value itself is unchanged (still the data source's or dataset's identifier); this mainly matters if you generated a client SDK from the OpenAPI document, since the generated parameter name will change.

### 6. Several fields were renamed

| Resource | v1 field | v2 field | Notes |
|  --- | --- | --- | --- |
| Data source / Dataset | `title` | `name` | Same string, new key. |
| Dataset (create request) | `primaryKeys` | `primaryKey` | Still an array of column IDs; only the key name changed. |
| Dataset ingestion | `ingestionId` | `id` | Applies to ingestion list and detail responses. |
| Dataset ingestion | `timestamp` | `initiatedAt` | Also gains `duration` and `initiatedBy`. |
| Dataset ingestion | `metrics` | `summary` / `errors` | `metrics.datasetMetrics` and `metrics.ingestionMetrics` are replaced by a flatter `summary` object plus a dedicated `errors` array. |


### 7. Creating a dataset now requires an explicit column schema

In v1, `POST /v1/datasets` accepted `title`, `dataSourceId`, and `primaryKeys`, none of which were strictly required. In v2, `POST /v2/datasets` requires `name`, `dataSourceId`, **and** `schema` — you must define the dataset's columns (`id` and `dataType`) up front:

```json
{
  "name": "Transactions",
  "dataSourceId": 4754489,
  "primaryKey": ["invoice_id"],
  "schema": [
    { "id": "invoice_id", "dataType": "string" },
    { "id": "occurred_at", "dataType": "datetime" },
    { "id": "amount", "dataType": "number" }
  ]
}
```

`dataType` accepts `datetime`, `number`, or `string` at creation time. (The full set of display data types — including `currency`, `duration`, and `percentage` — is available afterward through the column metadata endpoints.)

### 8. Listing every account is gone — organizations are scoped, and client accounts move to Accounts

`GET /v1/accounts` returned every account the API key could access, including client accounts. v2 has no equivalent list: `GET /v2/organization` returns only the single organization tied to the authenticated credential.

If your v1 integration iterated `/v1/accounts` to enumerate an agency's managed client accounts, switch to the new [Accounts](/docs/api/api.databox.com) resource (`GET /v2/accounts`) instead.

### 9. 404 responses are now consistent

v1 endpoints for a single resource generally only documented `400`/`401`/`403`. v2 adds `404_General` consistently across single-resource `GET`, `PATCH`, and `DELETE` operations. The error response shape itself — `code`, `message`, `field`, `type`, wrapped in an `errors` array — is unchanged from v1.

## Endpoint mapping

| v1 | v2 | Notes |
|  --- | --- | --- |
| `GET /v1/accounts` | `GET /v2/organization` | No longer lists client accounts; returns only the authenticated organization. Use `GET /v2/accounts` for client accounts. |
| `GET /v1/accounts/{accountId}/data-sources` | `GET /v2/data-sources` | `accountId` path parameter is gone — scoped to the authenticated organization automatically. Adds `search`, `connectionId`, sorting, and pagination. |
| `GET /v1/accounts/timezones` | `GET /v2/organization/timezones` | Moved under `/organization`; otherwise unchanged. |
| `GET /v1/auth/validate-key` | `GET /v2/auth/validate-key` | Unchanged, still `x-api-key` only. |
| `POST /v1/data-sources` | `POST /v2/data-sources` | `title` → `name`; `accountId` no longer accepted in the body (always created in the authenticated organization); internal `key` field removed. |
| `DELETE /v1/data-sources/{dataSourceId}` | `DELETE /v2/data-sources/{id}` | Same behavior. |
| `GET /v1/data-sources/{dataSourceId}/datasets` | `GET /v2/datasets?dataSourceId={id}` | Folded into the general dataset list endpoint, filtered by `dataSourceId`. Adds `search`, sorting, and pagination. |
| `POST /v1/datasets` | `POST /v2/datasets` | `title` → `name`; `primaryKeys` → `primaryKey`; `schema` is now required (see [above](#7-creating-a-dataset-now-requires-an-explicit-column-schema)). |
| `DELETE /v1/datasets/{datasetId}` | `DELETE /v2/datasets/{id}` | Same behavior. |
| `POST /v1/datasets/{datasetId}/purge` | `POST /v2/datasets/{id}/purge` | Same behavior. |
| `POST /v1/datasets/{datasetId}/data` | `POST /v2/datasets/{id}/data` | Request body (`records`) is unchanged; response now also includes a `status` field. |
| `GET /v1/datasets/{datasetId}/ingestions` | `GET /v2/datasets/{id}/ingestions` | List items rename `ingestionId` → `id` and `timestamp` → `initiatedAt`, and add `duration` and `initiatedBy`. |
| `GET /v1/datasets/{datasetId}/ingestions/{ingestionId}` | `GET /v2/datasets/{id}/ingestions/{ingestionId}` | Same renames as above; `metrics` is replaced by `summary` and a dedicated `errors` array. |


Everything else in v2 — Billing, Accounts, Connections, Databoards, Integrations, Metrics, Profile, Users, plus the new capabilities on Data Sources and Datasets — is new; there's no v1 equivalent to map from. See the [API Reference](/docs/api/api.databox.com) for the full set of operations.

## Migration checklist

- [ ] Update the base path from `/v1/` to `/v2/`.
- [ ] Read every successful response's payload from `data` instead of the response root.
- [ ] Read list results from `data.items` instead of a resource-named array key.
- [ ] Update pagination handling for zero-indexed `page` and the new `pageSize` default (25, max 100).
- [ ] Rename `title` → `name` and `primaryKeys` → `primaryKey` in any request bodies you construct.
- [ ] Add a `schema` (column `id` + `dataType`) to any dataset-creation requests.
- [ ] Replace `ingestionId` / `timestamp` field reads with `id` / `initiatedAt` when parsing ingestion responses.
- [ ] Replace any use of `GET /v1/accounts` to enumerate client accounts with `GET /v2/accounts`.
- [ ] If you generated a client from the v1 OpenAPI document, regenerate it from the [v2 spec](/docs/api/api.databox.com) rather than hand-patching paths.