---
title: "Vintages endpoints — API reference | Data Tactical Group"
route: "/docs/api/reference/vintages"
updated: "2026-10-23"
---

# Vintages

1 endpoint, generated from the API's own OpenAPI document. The data releases this credential can read.

## GET `/v2/vintages`

**The vintages this caller can see**

Credentials: API key or App session. Operation id `dataListVintages`.

Any authenticated caller: an API key (live or sandbox) or a session, any role. Not behind the entitlement gate, so a live key on a plan without the API add-on can read it, and it is not metered. Lists the vintage files of the caller's own scope, newest first: a live key or a session sees the real vintages and never learns a sandbox exists; a sandbox key sees only the sandbox vintages. A withdrawn vintage with no correction is not listed; a superseded one is listed with `superseded_by`. This is the list a release moves, so it is `Cache-Control: no-store`. Takes no query parameters. A session request records the person's presence (it cancels an open ownership claim on an organization they own).

### Parameters

**`X-DTG-Org` header · string (uuid)**

Session only: the organization the request acts in, when the person belongs to more than one (default: their own organization). An API key is bound to its organization; on a key this header must name that organization or be omitted. A malformed id, or an organization the caller is not an active member of, is 404 [`not_found`](/docs/api/errors#code-not-found).

### Responses

#### `200` success

The vintages.

As `application/json`.

**`X-RateLimit-Limit` header**

The per-minute request ceiling that applies.

**`X-RateLimit-Remaining` header**

Requests left in the current window.

**`X-RateLimit-Reset` header**

Seconds until the window refills: on every answer, the time until the bucket is full again; on a refusal, until a request is allowed (as `Retry-After`).

**`X-DTG-Sandbox` header**

Present, with the value `true`, on every response to a sandbox API key, success and problem alike; it is set as soon as the credential is known. Every value in a sandbox response is synthetic and must never be published as data. Absent for live keys and sessions.

**`Cache-Control` header**

`no-store`.

**`data` array of DataVintage always present**

Every readable vintage in the caller's scope that has not been withdrawn, newest first. A file the server cannot read (a build still being written) is left out rather than failing the list.

**`data[].id` string always present**

The build id (`20260913`; a sandbox key sees `sandbox-2026.1` style ids). Pass it as `vintage=` to pin a request to this vintage, which never changes once released.

**`data[].label` string or null always present**

The public name to cite: `DTG <year>.<N>`, N counting releases in the calendar year; a correction adds `r<N>` (`DTG 2026.3r1`); a sandbox vintage is `SANDBOX 2026.1`. Null only for a vintage no manifest labels.

**`data[].built_at` string or null always present**

When the build finished, as its manifest records it (ISO 8601); null if not recorded.

**`data[].current` boolean always present**

True for the vintage requests read when no `vintage=` is given. Exactly one row is current; the pointer moves atomically at release.

**`data[].entitled` boolean always present**

Whether this caller may request it as `vintage=`: the current vintage always, earlier ones when the plan includes prior vintages (every paid plan), and a superseded one never, whatever the plan. Every sandbox vintage is entitled for a sandbox key.

**`data[].superseded_by` string**

Present only on a vintage withdrawn and replaced by a correction: the id of the replacement. A request pinned to this vintage answers 404 [`vintage_superseded`](/docs/api/errors#code-vintage-superseded). (A vintage withdrawn with no correction yet is not listed at all.)

**`data[].sandbox` true**

Present, and true, on every row a sandbox key sees: a synthetic vintage.

**`meta` object**

Sandbox keys only.

**`meta.sandbox` true always present**

Always true: these are synthetic vintages.

#### `400` error

Bad request. Codes: [`unknown_parameter`](/docs/api/errors#code-unknown-parameter) (a query parameter this route does not take; `parameters[]` names them), [`repeated_parameter`](/docs/api/errors#code-repeated-parameter) (a parameter given more than once; `parameter`), [`bad_request`](/docs/api/errors#code-bad-request) (more than 50 query parameters).

As `application/problem+json`.

#### `401` error

Unauthenticated. Codes: [`unauthenticated`](/docs/api/errors#code-unauthenticated) (no credential, or an API key or session that is unknown or expired); [`key_revoked`](/docs/api/errors#code-key-revoked) (an API key that was revoked: `revoked_at`, and `reason` -- `holder`, `admin`, `member_removed`, `seat_removed`, `api_disabled`, `addon_ended`, [`account_closed`](/docs/api/errors#code-account-closed), [`org_closed`](/docs/api/errors#code-org-closed), `retired`, or null for a key revoked before T110 -- and a sentence saying when and why).

As `application/problem+json`.

#### `403` error

Forbidden. Codes: [`no_membership`](/docs/api/errors#code-no-membership) (the account has no active organization membership), [`account_suspended`](/docs/api/errors#code-account-suspended) (O56: the caller's own account is suspended by DTG; `reason` where recorded), [`org_suspended`](/docs/api/errors#code-org-suspended) (the organization is suspended; `organization` {id, name} and, where recorded, `reason`), [`org_closed`](/docs/api/errors#code-org-closed) (the organization is closed; `organization`), [`wrong_instance`](/docs/api/errors#code-wrong-instance) (a key of the mode this process does not serve, for example a sandbox key on a live-only process; `expected`, and `base_url` naming the address that serves it).

As `application/problem+json`.

#### `404` error

Not found. Codes: [`not_found`](/docs/api/errors#code-not-found) (an `X-DTG-Org` header naming an organization the caller does not belong to).

As `application/problem+json`.

#### `414` error

URI too long. Codes: [`uri_too_long`](/docs/api/errors#code-uri-too-long) (the request URL is longer than the configured maximum, 8,192 bytes by default).

As `application/problem+json`.

#### `429` error

Rate limited, and only that: [`rate_limited`](/docs/api/errors#code-rate-limited) (over the 120 requests a minute per credential or 300 a minute per organization; the sandbox ceilings are lower). `Retry-After` and `X-RateLimit-*` say when to retry. This route is not admission-gated or metered.

As `application/problem+json`.

**`Retry-After` header**

Seconds to wait before retrying.

**`X-RateLimit-Limit` header**

The per-minute request ceiling that applies.

**`X-RateLimit-Remaining` header**

Requests left in the current window.

**`X-RateLimit-Reset` header**

Seconds until the window refills: on every answer, the time until the bucket is full again; on a refusal, until a request is allowed (as `Retry-After`).

#### `500` error

Server error. Codes: [`internal_error`](/docs/api/errors#code-internal-error) (for example a vintage file the server cannot read).

As `application/problem+json`.

Problem codes: [`unknown_parameter`](/docs/api/errors#code-unknown-parameter) (400), [`repeated_parameter`](/docs/api/errors#code-repeated-parameter) (400), [`bad_request`](/docs/api/errors#code-bad-request) (400), [`unauthenticated`](/docs/api/errors#code-unauthenticated) (401), [`key_revoked`](/docs/api/errors#code-key-revoked) (401), [`account_closed`](/docs/api/errors#code-account-closed) (401), [`org_closed`](/docs/api/errors#code-org-closed) (401), [`no_membership`](/docs/api/errors#code-no-membership) (403), [`account_suspended`](/docs/api/errors#code-account-suspended) (403), [`org_suspended`](/docs/api/errors#code-org-suspended) (403), [`org_closed`](/docs/api/errors#code-org-closed) (403), [`wrong_instance`](/docs/api/errors#code-wrong-instance) (403), [`not_found`](/docs/api/errors#code-not-found) (404), [`uri_too_long`](/docs/api/errors#code-uri-too-long) (414), [`rate_limited`](/docs/api/errors#code-rate-limited) (429), [`internal_error`](/docs/api/errors#code-internal-error) (500). Every problem is a [problem document](/docs/api/errors).

Generated from `taigan/openapi.yaml` at catahoula `77925fab712f`(API document version 2.0).
