---
title: "What one account has confirmed about its own sell-out reports"
method: GET
path: "/api/v1/sell-out/declaration"
tags: ["sell_out"]
---

# What one account has confirmed about its own sell-out reports

`GET /api/v1/sell-out/declaration`

## Request

- Base URL: `https://api.app.tightly.io`
- URL: `https://api.app.tightly.io/api/v1/sell-out/declaration`
- Auth: HTTP bearer

The four answers one account has confirmed about its own sell-out reports, or null when nobody has answered yet: which day its week ends on, whether the figures cover stores, distribution centres or the whole account, the currency and whether prices include tax, and whether a product missing from a file means it sold none or means the retailer did not report it. `account_id` is required.

Null is the meaningful case. The declaration is a precondition of an import rather than a setting, so an account with none has its files refused until a person answers.

The four exist because every default is wrong for about half of all accounts. One retailer writes an explicit zero for a product that did not sell; another omits the row. Guess wrong and half the book shows healthy products as dead, with the row count looking correct either way.

Every machine value is served beside the sentence a person reads for it (`covers`, `prices_are`, `missing_row_means`, `week_ends_on`), so no surface has to keep its own translation table. `confirmed_by` is the author's id and `confirmed_by_name` the name resolved for it, with the name null rather than the id where there is none.

Sold with Essentials+: without Tightly Connect the answer is 403 `plan_excludes`.

Scope: `sell_out:read`.

## Query parameters

- `account_id` string, required

## Headers

- `Tightly-Version` string

## Response `200`

The confirmed declaration, `week_ends_on` / `week_anchor_dow`, `covers` / `location_grain`, `currency`, `prices_are` / `price_tax_basis`, `missing_row_means` / `absence_convention`, `confirmed_by`, `confirmed_by_name`, `confirmed_at`, or `data: null` when nobody has confirmed for this account yet.

- object

## Other responses

- `400`: No account was named
- `401`: No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
- `403`: The key may not reach this operation. `plan_excludes` when Sell-out is sold with Essentials+ and this organisation's plan does not include it; `scope_missing` when the key does not hold Sell-out; `organization_mismatch` when the path names an organisation that is not the key's; `ip_not_allowed` when the caller's address is outside the key's allowlist; `account_mismatch` when a key issued to one account names another in `account_id`, and the sentence names both accounts.
- `429`: The key has spent its allowance for this minute. 600 reads and 120 writes a minute, counted per key, refused calls included. `Retry-After` says how long to wait.
- `503`: The database is briefly out of reach, which is what a failover or a full connection pool looks like from outside. Wait the seconds `Retry-After` names and send the request again. A read is safe to repeat. A write is not, because the connection was lost in the middle of it, so read the object back before sending it a second time. Branch on the status rather than on `code`, which is `POSTGRES_UNAVAILABLE` from one of the two seams that raise this and `SERVICE_UNAVAILABLE` from the other.

---

[API](https://skmtc.dev/tightly/apis/tightly-api.md) · [All operations](https://skmtc.dev/tightly/apis/tightly-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tightly/apis/tightly-api/revisions/199f7eb35afb?raw)
