# invoices.qstConfirm

Confirm the reviewed QST setup for this organization with the person's explicit approval of the current invoices.qstReview calculation and facts. Pass its reviewHash and expectedSettingsRevision, the same saved invoice or proposed draft, reviewed facts, and an idempotency key. Changed records or settings require a fresh review. Saves the registration basis for later invoices while continuing to recheck qualifying sales, effective dates, customer status and missing evidence. Confirmation does not register the company with Revenu Québec, cancel registration, or send an invoice. Administrator only.

`POST /api/v1/accounting/invoices.qstConfirm`

Permissions: `accounting:read`, `accounting:write`, `accounting:admin` · Roles: admin · Idempotency key required

MCP tool: `accounting_invoices_qst_confirm`

## Fields

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `id` | string (ID) |  | The record's ID. |
| `draft` | object |  | No other fields. |
| `draft.partyId` | string (ID) | Yes | The ID of a customer or vendor account, from parties.list. |
| `draft.title` | string |  | A short title. at most 200 characters. |
| `draft.issueDate` | string or null |  | The date the document was issued, as YYYY-MM-DD. |
| `draft.dueDate` | string or null |  | The date payment is due, as YYYY-MM-DD. |
| `draft.currency` | string |  | Three-letter currency code, such as CAD or USD. |
| `draft.lines` | array of objects |  | at most 100 items. |
| `draft.lines[].id` | string |  | The record's ID. at most 64 characters. |
| `draft.lines[].description` | string | Yes | A short description. 1–500 characters. |
| `draft.lines[].quantity` | string |  |  |
| `draft.lines[].unitAmountMinor` | string |  | An amount in cents (the currency's smallest unit), written as a whole-number string such as "1250" for $12.50. Whole number written as a string, may be negative. |
| `draft.lines[].isHeader` | boolean |  |  |
| `draft.lines[].taxCode` | enum |  | One of: `standard`, `exempt`, `zero_rated`. |
| `draft.taxTreatment` | enum or null |  | One of: `auto`, `unknown`, `hst`, `gst`, `gst_qst`, `zero_rated`, `exempt`, `none`, `custom`. |
| `draft.taxRateCode` | enum or string or null |  |  |
| `draft.paymentMethodIds` | array of strings (ID) |  | A list of record IDs. at most 10 items. |
| `draft.payUrl` | string (uri) or null |  |  |
| `draft.notes` | string |  | Notes kept with the record. at most 4000 characters. |
| `draft.memo` | string |  | at most 4000 characters. |
| `draft.terms` | object |  | No other fields. |
| `draft.terms.code` | enum | Yes | One of: `due_on_receipt`, `net_7`, `net_15`, `net_30`, `net_45`, `net_60`, `custom`, `split_50_50`, `monthly`. |
| `draft.terms.days` | integer or null |  |  |
| `draft.billToContactId` | string or null |  |  |
| `draft.projectId` | string (ID) or null |  |  |
| `facts` | object | Yes | No other fields. |
| `facts.standardServicesOnly` | boolean |  | Default `false`. |
| `facts.supplierOutsideQuebec` | boolean or null | Yes |  |
| `facts.carriesOnBusinessInQuebec` | boolean or null | Yes |  |
| `facts.registration` | enum | Yes | One of: `unknown`, `none`, `specified`, `general`. |
| `facts.registrationNumber` | string or null | Yes |  |
| `facts.effectiveDate` | string or null | Yes |  |
| `facts.allSalesRecorded` | boolean | Yes |  |
| `facts.additionalSales` | array of objects | Yes | at most 200 items. |
| `facts.additionalSales[].date` | string | Yes | A date, as YYYY-MM-DD. |
| `facts.additionalSales[].amountCadMinor` | string | Yes | An amount in cents (the currency's smallest unit), written as a whole-number string such as "1250" for $12.50. Matches ^\d{1,18}$. |
| `facts.additionalSales[].description` | string | Yes | A short description. 1–200 characters. |
| `facts.expectedAdditionalSalesCadMinor` | string | Yes | An amount in cents (the currency's smallest unit), written as a whole-number string such as "1250" for $12.50. Matches ^\d{1,18}$. |
| `facts.expectedSalesAsOf` | string or null | Yes |  |
| `facts.customerGeneralQstVerifiedOn` | string or null |  | Default `null`. |
| `facts.residencyEvidence` | array of strings |  | at most 5 items; each 1–200 characters. Default `[]`. |
| `facts.customerGeneralQstNumber` | string or null | Yes |  |
| `clearCustomerGeneralQst` | boolean |  | Default `false`. |
| `reviewHash` | string | Yes | SHA-256 hash as 64 lowercase hex characters. |
| `expectedSettingsRevision` | integer | Yes | The related record's current revision, from the last time you read it. 0 to 9007199254740991. |
| `idempotencyKey` | string | Yes | Any unique text you generate once per intended change, so a retried request only happens once. Send it as the Idempotency-Key header instead if you prefer; if you send both they must match. 8–200 characters. |

## Example request

```bash
curl https://app.getoatmilk.com/api/v1/accounting/invoices.qstConfirm \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "facts": {
    "supplierOutsideQuebec": true,
    "carriesOnBusinessInQuebec": true,
    "registration": "unknown",
    "registrationNumber": "example",
    "effectiveDate": "2026-09-30",
    "allSalesRecorded": true,
    "additionalSales": [
      {
        "date": "2026-09-30",
        "amountCadMinor": "1250",
        "description": "Synthetic example from the docs"
      }
    ],
    "expectedAdditionalSalesCadMinor": "1250",
    "expectedSalesAsOf": "example",
    "customerGeneralQstNumber": "example"
  },
  "reviewHash": "9f2b5c1d7e3a4b6c8d0e2f4a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b4c",
  "expectedSettingsRevision": 3,
  "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d"
}'
```

Reference page: https://app.getoatmilk.com/docs/api/invoices.qstConfirm
