# ai.sandbox.evaluate

Evaluate a supplied fixture against saved or draft automation settings without writing anything. kind routing classifies an email fixture; kind matching scores a receipt against bank candidates; kind document reads a real file exactly as the inbox does (file {filename, mimeType, contentBase64}, up to 2 MB: a receipt, invoice or statement as a PDF, image, office or text document, or an original .eml email, which is classified first): every page is turned into images with logos and signature graphics set aside, read twice with vision and settled by the stronger model when the readings disagree, and checked as the books would take it. It returns the classifier answer, the facts, the vision check, the entry or flags for each document, and the parts read. kind record reads a kept-record file (file as for document, recordKind tax_document, company_document or other) exactly as Tax › Records reads one, with the same pages, model, prompt and schema, and returns its fields, warnings, model, prompt version and parts; for a company record also describesCompany, wouldFill (filled, nothing_new, other_company or needs_admin) and the profile fields it fills or differs on. kind email runs the email-sorting classifier on an email already in the company inbox (messageId), rebuilt from what was stored when it arrived, and returns the new decision with what was decided at the time (example.stored). kind receipt runs the matcher on a receipt entry (entryId) against its current bank and card candidates (draft may also set autoApply). Both accept the same draft model and thresholds as routing and matching. Nothing is saved. Use it to test the pipeline without the dashboard, and to test custom models before saving them.

`GET | POST /api/v1/accounting/ai.sandbox.evaluate`

Permissions: `accounting:read` · Roles: admin

MCP tool: `accounting_ai_sandbox_evaluate`

## Fields

#### kind: "routing"

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `kind` | "routing" | Yes | Which kind of record or job this is. |
| `mailboxKey` | string |  | at most 40 characters. Default `"accounting"`. |
| `fixture` | object | Yes | No other fields. |
| `fixture.subject` | string | Yes | at most 2000 characters. |
| `fixture.text` | string | Yes | at most 20000 characters. |
| `fixture.senderDomain` | string | Yes | at most 200 characters. |
| `fixture.attachmentNames` | array of strings | Yes | at most 30 items; each at most 300 characters. |
| `useSavedConfig` | boolean |  | Default `true`. |
| `draft` | object |  | No other fields. Default `{}`. |
| `draft.model` | string |  | 1–120 characters. |
| `draft.matchThresholds` | object |  | No other fields. |
| `draft.matchThresholds.selectedProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.providerConfidence` | number |  | 0 to 1. |
| `draft.matchThresholds.sameEventProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.runnerUpMargin` | number |  | 0 to 1. |
| `draft.routingThresholds` | object |  | No other fields. |
| `draft.routingThresholds.probability` | number |  | 0 to 1. |
| `draft.routingThresholds.confidence` | number |  | 0 to 1. |

#### kind: "matching"

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `kind` | "matching" | Yes | Which kind of record or job this is. |
| `fixture` | object | Yes | No other fields. |
| `fixture.receipt` | object | Yes | No other fields. |
| `fixture.receipt.entryId` | string | Yes | The ID of an accounting entry, from entries.list or attention.mine. 1–100 characters. |
| `fixture.receipt.revision` | integer | Yes | 0 to 9007199254740991. |
| `fixture.receipt.date` | string | Yes | A date, as YYYY-MM-DD. at most 10 characters. |
| `fixture.receipt.currency` | string | Yes | Three-letter currency code, such as CAD or USD. at most 3 characters. |
| `fixture.receipt.amountMinor` | string | Yes | An amount in cents (the currency's smallest unit), written as a whole-number string such as "1250" for $12.50. at most 30 characters. |
| `fixture.receipt.type` | enum | Yes | One of: `expense`, `income`, `income_refund`, `refund`, `fee`, `transfer`, `suspense`. |
| `fixture.receipt.merchant` | string | Yes | at most 300 characters. |
| `fixture.receipt.description` | string | Yes | A short description. at most 2000 characters. |
| `fixture.receipt.invoiceNumber` | string or null |  |  |
| `fixture.receipt.sourceEvidenceIds` | array of strings | Yes | A list of record IDs. at most 20 items; each at most 100 characters. |
| `fixture.receipt.paymentAccountId` | string or null | Yes | The card or account the purchase was paid with, from accounts.list. |
| `fixture.receipt.allocatedMinor` | string | Yes | An amount in cents (the currency's smallest unit), written as a whole-number string such as "1250" for $12.50. at most 30 characters. |
| `fixture.receipt.split` | boolean | Yes |  |
| `fixture.receipt.closed` | boolean | Yes |  |
| `fixture.receipt.requiresReview` | boolean | Yes |  |
| `fixture.candidates` | array of objects | Yes | 1–5 items. |
| `fixture.candidates[].transactionId` | string | Yes | The ID of a bank or card transaction, from transactions.list. 1–100 characters. |
| `fixture.candidates[].revision` | integer | Yes | 0 to 9007199254740991. |
| `fixture.candidates[].provider` | enum | Yes | One of: `wise`, `rbc`, `stripe`, `other`. |
| `fixture.candidates[].accountId` | string | Yes | The ID of a bank, card or payment account, from accounts.list. 1–100 characters. |
| `fixture.candidates[].date` | string | Yes | A date, as YYYY-MM-DD. at most 10 characters. |
| `fixture.candidates[].currency` | string | Yes | Three-letter currency code, such as CAD or USD. at most 3 characters. |
| `fixture.candidates[].amountMinor` | string | Yes | An amount in cents (the currency's smallest unit), written as a whole-number string such as "1250" for $12.50. at most 30 characters. |
| `fixture.candidates[].availableAmountMinor` | string | Yes | An amount in cents (the currency's smallest unit), written as a whole-number string such as "1250" for $12.50. at most 30 characters. |
| `fixture.candidates[].description` | string | Yes | A short description. at most 2000 characters. |
| `fixture.candidates[].reference` | string | Yes | at most 1000 characters. |
| `fixture.candidates[].sourceEvidenceIds` | array of strings | Yes | A list of record IDs. at most 20 items; each at most 100 characters. |
| `fixture.candidates[].availability` | enum | Yes | One of: `unallocated`, `bank_entry_without_receipt`, `partial`, `allocated`, `unavailable`. |
| `fixture.candidates[].status` | enum | Yes | Only include records with this status. One of: `posted`, `pending`, `failed`. |
| `fixture.candidates[].reversed` | boolean | Yes |  |
| `fixture.candidates[].closed` | boolean | Yes |  |
| `fixture.candidates[].transactionType` | enum |  | One of: `payment`, `refund`, `transfer`, `fee`, `unknown`. |
| `useSavedConfig` | boolean |  | Default `true`. |
| `draft` | object |  | No other fields. Default `{}`. |
| `draft.model` | string |  | 1–120 characters. |
| `draft.matchThresholds` | object |  | No other fields. |
| `draft.matchThresholds.selectedProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.providerConfidence` | number |  | 0 to 1. |
| `draft.matchThresholds.sameEventProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.runnerUpMargin` | number |  | 0 to 1. |
| `draft.routingThresholds` | object |  | No other fields. |
| `draft.routingThresholds.probability` | number |  | 0 to 1. |
| `draft.routingThresholds.confidence` | number |  | 0 to 1. |

#### kind: "document"

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `kind` | "document" | Yes | Which kind of record or job this is. |
| `file` | object | Yes | No other fields. |
| `file.filename` | string | Yes | The file's name, including its extension. 1–200 characters. |
| `file.mimeType` | string | Yes | The file's type, such as image/jpeg or application/pdf. 3–120 characters. |
| `file.contentBase64` | string | Yes | The file's exact bytes, encoded as base64. 4–2900000 characters. |
| `documentKind` | enum |  | One of: `receipt`, `invoice`, `credit_note`, `statement`, `other`, `unknown`. |
| `useSavedConfig` | boolean |  | Default `true`. |
| `draft` | object |  | No other fields. Default `{}`. |
| `draft.model` | string |  | 1–120 characters. |
| `draft.matchThresholds` | object |  | No other fields. |
| `draft.matchThresholds.selectedProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.providerConfidence` | number |  | 0 to 1. |
| `draft.matchThresholds.sameEventProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.runnerUpMargin` | number |  | 0 to 1. |
| `draft.routingThresholds` | object |  | No other fields. |
| `draft.routingThresholds.probability` | number |  | 0 to 1. |
| `draft.routingThresholds.confidence` | number |  | 0 to 1. |

#### kind: "record"

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `kind` | "record" | Yes | Which kind of record or job this is. |
| `recordKind` | enum | Yes | One of: `tax_document`, `company_document`, `other`. |
| `file` | object | Yes | No other fields. |
| `file.filename` | string | Yes | The file's name, including its extension. 1–200 characters. |
| `file.mimeType` | string | Yes | The file's type, such as image/jpeg or application/pdf. 3–120 characters. |
| `file.contentBase64` | string | Yes | The file's exact bytes, encoded as base64. 4–2900000 characters. |

#### kind: "email"

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `kind` | "email" | Yes | Which kind of record or job this is. |
| `messageId` | string (ID) | Yes | The ID of the related record. |
| `useSavedConfig` | boolean |  | Default `true`. |
| `draft` | object |  | No other fields. Default `{}`. |
| `draft.model` | string |  | 1–120 characters. |
| `draft.matchThresholds` | object |  | No other fields. |
| `draft.matchThresholds.selectedProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.providerConfidence` | number |  | 0 to 1. |
| `draft.matchThresholds.sameEventProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.runnerUpMargin` | number |  | 0 to 1. |
| `draft.routingThresholds` | object |  | No other fields. |
| `draft.routingThresholds.probability` | number |  | 0 to 1. |
| `draft.routingThresholds.confidence` | number |  | 0 to 1. |

#### kind: "receipt"

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `kind` | "receipt" | Yes | Which kind of record or job this is. |
| `entryId` | string (ID) | Yes | The ID of an accounting entry, from entries.list or attention.mine. |
| `useSavedConfig` | boolean |  | Default `true`. |
| `draft` | object |  | No other fields. Default `{}`. |
| `draft.model` | string |  | 1–120 characters. |
| `draft.matchThresholds` | object |  | No other fields. |
| `draft.matchThresholds.selectedProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.providerConfidence` | number |  | 0 to 1. |
| `draft.matchThresholds.sameEventProbability` | number |  | 0 to 1. |
| `draft.matchThresholds.runnerUpMargin` | number |  | 0 to 1. |
| `draft.routingThresholds` | object |  | No other fields. |
| `draft.routingThresholds.probability` | number |  | 0 to 1. |
| `draft.routingThresholds.confidence` | number |  | 0 to 1. |
| `draft.autoApply` | boolean |  |  |

## Example request

```bash
curl https://app.getoatmilk.com/api/v1/accounting/ai.sandbox.evaluate \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "kind": "routing",
  "fixture": {
    "subject": "example",
    "text": "example",
    "senderDomain": "example",
    "attachmentNames": [
      "Synthetic Ventures Inc."
    ]
  }
}'
```

Reference page: https://app.getoatmilk.com/docs/api/ai.sandbox.evaluate
