# Search manual taxable documents

Operation ID: `searchManualTaxableDocument`

Group: Accounting › Tax Documents › Manual Taxable Documents

[Open in the interactive reference](https://docs.api.lensing.ai/lensing/v1/endpoints/searchManualTaxableDocument)

`POST /tax-documents/manual-taxable-documents/search`

Read-only: A read that takes its filters in the body. Changes nothing, and ignores Idempotency-Key.

Searches manual taxable documents, also called ad hoc documents. Each match is the full record, including its lines. Use it to match on customer name, document number, or the text of the title or description.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Api-Version` | header | string · v1 | yes | The API version this request targets, named by its public identifier. Required on every request; omitting it, or naming a version this company does not have, is answered with 400. This document describes version `v1`. |

## Request body

Required, `application/json`: searchManualTaxableDocumentInput.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filters` | object | no | Search filters, nested as one object so they map onto the POST body. All are optional and are ANDed; omitting every one of them matches all documents. Omit the whole object to do exactly that. |
| `filters.id` | string | no | Exact match on a document's id (a UUID). This is how a single known document is fetched. |
| `filters.taxDocumentNumber` | string | no | Exact match on the system-generated tax document number. In the body because a document number must not travel in a URL. |
| `filters.documentNumber` | string | no | Exact match on the source document number — the counterparty's own number, or one carried over from an external system. In the body on the same grounds as taxDocumentNumber. |
| `filters.type` | array<string> | no | Restrict to documents of any of these kinds. Allowed values: 'outgoingInvoice', 'outgoingCredit', 'incomingInvoice', 'incomingCredit'; an unrecognised value simply matches nothing. An empty array does not constrain. |
| `filters.paymentStatus` | array<string> | no | Restrict to documents in any of these settlement statuses. Allowed values: 'paid', 'partiallyPaid', 'unpaid', 'noPaymentNeeded', 'voided', 'applied', 'unapplied', 'partiallyApplied', 'noApplicationNeeded'; an unrecognised value simply matches nothing. An empty array does not constrain. |
| `filters.currency` | array<string> | no | Restrict to documents in any of these currencies, as 3-letter ISO 4217 codes. An empty array does not constrain. |
| `filters.title` | string | no | Case-insensitive SUBSTRING match on the document title. In the body because free text must never travel in a URL. |
| `filters.description` | string | no | Case-insensitive SUBSTRING match on the free-text document description. In the body because free text must never travel in a URL. |
| `filters.paymentTerms` | string | no | Case-insensitive SUBSTRING match on the payment terms recorded on the document. In the body because free text must never travel in a URL. |
| `filters.customerId` | string | no | Restrict to documents issued to this customer, given as the customer id (a UUID). An id that matches no customer yields an empty page, not an error. |
| `filters.customerName` | string | no | Case-insensitive SUBSTRING match on the customer's name. In the body precisely because a counterparty name must never travel in a URL. |
| `filters.customerNumber` | string | no | Exact match on the customer's system-generated customer number. In the body on the same grounds as customerName. |
| `filters.entityId` | string | no | Restrict to documents belonging to this legal entity, given as the entity id (a UUID). An id that matches no entity yields an empty page, not an error. |
| `filters.entityName` | string | no | Case-insensitive SUBSTRING match on the legal entity's name. In the body because it names internal organisational structure. |
| `filters.invoiceDate` | object | no | Restrict to documents issued in this date window. Both bounds are calendar dates (YYYY-MM-DD) and are INCLUSIVE; omit either side to leave it open-ended. |
| `filters.invoiceDate.start` | string | no | Earliest issue date to include, as a calendar date (YYYY-MM-DD). Inclusive. Omit for no lower bound. |
| `filters.invoiceDate.end` | string | no | Latest issue date to include, as a calendar date (YYYY-MM-DD). Inclusive. Omit for no upper bound. |
| `filters.serviceDate` | object | no | Restrict to documents whose service date falls in this window. Both bounds are calendar dates (YYYY-MM-DD) and are INCLUSIVE; omit either side to leave it open-ended. |
| `filters.serviceDate.start` | string | no | Earliest service date to include, as a calendar date (YYYY-MM-DD). Inclusive. Omit for no lower bound. |
| `filters.serviceDate.end` | string | no | Latest service date to include, as a calendar date (YYYY-MM-DD). Inclusive. Omit for no upper bound. |
| `filters.dueDate` | object | no | Restrict to documents falling due in this window. Both bounds are calendar dates (YYYY-MM-DD) and are INCLUSIVE; omit either side to leave it open-ended. |
| `filters.dueDate.start` | string | no | Earliest due date to include, as a calendar date (YYYY-MM-DD). Inclusive. Omit for no lower bound. |
| `filters.dueDate.end` | string | no | Latest due date to include, as a calendar date (YYYY-MM-DD). Inclusive. Omit for no upper bound. |
| `filters.lastModifiedDate` | object | no | Restrict to documents changed in this window — the incremental-sync filter. Both bounds are ISO 8601 UTC timestamps (YYYY-MM-DDTHH:mm:ss.sssZ) and are INCLUSIVE; omit either side to leave it open-ended. |
| `filters.lastModifiedDate.start` | string | no | Earliest change instant to include, as ISO 8601 UTC (YYYY-MM-DDTHH:mm:ss.sssZ). Inclusive. Omit for no lower bound. |
| `filters.lastModifiedDate.end` | string | no | Latest change instant to include, as ISO 8601 UTC (YYYY-MM-DDTHH:mm:ss.sssZ). Inclusive. Omit for no upper bound. |
| `filters.totalAmount` | object | no | Restrict by gross document total, in each document's own currency (see the currency filter to pin one). Both bounds are INCLUSIVE; omit either side to leave it open-ended. |
| `filters.totalAmount.min` | decimal | no | Smallest gross total to include. Inclusive. Omit for no lower bound. |
| `filters.totalAmount.max` | decimal | no | Largest gross total to include. Inclusive. Omit for no upper bound. |
| `filters.totalOpenAmount` | object | no | Restrict by remaining open balance, in each document's own currency. Set min to a value just above zero to select the documents still outstanding. Both bounds are INCLUSIVE; omit either side to leave it open-ended. |
| `filters.totalOpenAmount.min` | decimal | no | Smallest open balance to include. Inclusive. Omit for no lower bound. |
| `filters.totalOpenAmount.max` | decimal | no | Largest open balance to include. Inclusive. Omit for no upper bound. |
| `page` | object | no | Pagination controls. Omit for the first page. |
| `page.cursor` | string | no | Opaque forward cursor from a previous response's pagination.nextCursor; omit for the first page. Do not construct manually. |
| `page.size` | number | no | Maximum number of documents to return. Defaults to 50, capped at 200; the server may return fewer, but never more. |

```json
{
  "filters": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "taxDocumentNumber": "<taxDocumentNumber>",
    "documentNumber": "<documentNumber>",
    "type": [
      "<type>"
    ],
    "paymentStatus": [
      "<paymentStatus>"
    ],
    "currency": [
      "<currency>"
    ],
    "title": "<title>",
    "description": "<description>",
    "paymentTerms": "<paymentTerms>",
    "customerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "customerName": "<customerName>",
    "customerNumber": "<customerNumber>",
    "entityId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "entityName": "<entityName>",
    "invoiceDate": {
      "start": "<start>",
      "end": "<end>"
    },
    "serviceDate": {
      "start": "<start>",
      "end": "<end>"
    },
    "dueDate": {
      "start": "<start>",
      "end": "<end>"
    },
    "lastModifiedDate": {
      "start": "<start>",
      "end": "<end>"
    },
    "totalAmount": {
      "min": "19.99",
      "max": "19.99"
    },
    "totalOpenAmount": {
      "min": "19.99",
      "max": "19.99"
    }
  },
  "page": {
    "cursor": "<cursor>",
    "size": 0
  }
}
```

## Response

`200` Success

Under `data` (searchManualTaxableDocumentOutput):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | array<object> | yes | Matching manual taxable documents for this page, newest first. Empty when nothing matches. |
| `items[].id` | string | yes | Id of the manual taxable document (a UUID) — the public identifier of this record. |
| `items[].type` | string | no | Kind of document. One of 'outgoingInvoice', 'outgoingCredit', 'incomingInvoice', 'incomingCredit'. An outgoingInvoice is a customer-facing invoice whose incoming payment can be matched to a bank deposit. |
| `items[].taxDocumentNumber` | string | no | System-generated tax document number, unique per tenant and human-readable. Absent until one has been assigned. |
| `items[].documentNumber` | string | no | Document number as it appears on the source document — the counterparty's own number for an incoming document, or the number carried over from an external system. Distinct from taxDocumentNumber, which Everest assigns. |
| `items[].title` | string | no | Title of the document, as shown on the record. |
| `items[].description` | string | no | Free-text description of the document. |
| `items[].invoiceDate` | date | no | Date the document was issued, as a calendar date (YYYY-MM-DD). |
| `items[].serviceDate` | date | no | Date the underlying service was provided, as a calendar date (YYYY-MM-DD). Drives the tax point where it differs from the invoice date. |
| `items[].dueDate` | date | no | Date payment falls due, as a calendar date (YYYY-MM-DD). Absent when no due date has been set. |
| `items[].currency` | string | no | Currency of this document as a 3-letter ISO 4217 code (e.g. USD, EUR, GBP). It governs every amount on the record, on the header and on every line alike. |
| `items[].paymentStatus` | string | no | Settlement status of the document. One of 'paid', 'partiallyPaid', 'unpaid', 'noPaymentNeeded', 'voided', 'applied', 'unapplied', 'partiallyApplied', 'noApplicationNeeded'. |
| `items[].paymentTerms` | string | no | Payment terms recorded on the document, as free text (e.g. 'Net 30'). |
| `items[].totalTaxAmount` | decimal | no | Sum of the tax amounts of every line, in the document currency (see currency). |
| `items[].totalAmount` | decimal | no | Sum of the total amounts of every line — the gross document total, in the document currency (see currency). |
| `items[].totalAllocatedAmount` | decimal | no | Amount already allocated to this document by payments or credits, in the document currency (see currency). |
| `items[].totalOpenAmount` | decimal | no | Remaining unallocated balance on this document, in the document currency (see currency). Greater than zero means the document is still open. |
| `items[].hasAttachment` | boolean | no | True when the document has at least one attachment. The attachments themselves are not published by this API; document delivery is a separate concern with its own permission. |
| `items[].customerId` | string | no | Id of the customer the document is issued to (a UUID). Set on customer-facing documents; absent on vendor or employee ones. |
| `items[].customerName` | string | no | Display name of the customer. Personal and counterparty data. |
| `items[].customerNumber` | string | no | System-generated customer number of the customer, unique per tenant. |
| `items[].entityId` | string | no | Id of the legal entity the document belongs to (a UUID). |
| `items[].entityName` | string | no | Name of the legal entity the document belongs to. |
| `items[].lastModifiedDate` | date-time | yes | Instant the document record last changed, as ISO 8601 UTC (YYYY-MM-DDTHH:mm:ss.sssZ). Poll on this to sync incrementally rather than re-reading the whole collection. |
| `items[].lines` | array<object> | no | Lines of the document, each carrying one taxable position. Empty on a document with no lines. All line amounts are in the document currency (see currency). |
| `items[].lines[].id` | string | yes | Id of the document line (a UUID). |
| `items[].lines[].lineNumber` | string | no | System-generated line number within the document. Absent until one has been assigned. |
| `items[].lines[].description` | string | no | Free-text description of the line item. |
| `items[].lines[].taxableBasis` | decimal | no | Basis amount the tax is calculated on, in the document currency (see currency). |
| `items[].lines[].taxAmount` | decimal | no | Tax charged on the line, in the document currency (see currency). |
| `items[].lines[].totalAmount` | decimal | no | Line total including tax, in the document currency (see currency). |
| `pagination` | object | yes | Pagination cursor for this page. |
| `pagination.nextCursor` | string | no | Opaque cursor to pass as page.cursor for the next page; absent on the last page (mirrors the list/v1 data-set pagination.nextCursor). |
| `pagination.hasMore` | boolean | yes | True when more matches remain beyond this page (mirrors the list/v1 data-set pagination.hasMore). |

```json
{
  "data": {
    "items": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "type": "<type>",
        "taxDocumentNumber": "<taxDocumentNumber>",
        "documentNumber": "<documentNumber>",
        "title": "<title>",
        "description": "<description>",
        "invoiceDate": "2026-01-15",
        "serviceDate": "2026-01-15",
        "dueDate": "2026-01-15",
        "currency": "<currency>",
        "paymentStatus": "<paymentStatus>",
        "paymentTerms": "<paymentTerms>",
        "totalTaxAmount": "19.99",
        "totalAmount": "19.99",
        "totalAllocatedAmount": "19.99",
        "totalOpenAmount": "19.99",
        "hasAttachment": true,
        "customerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "customerName": "<customerName>",
        "customerNumber": "<customerNumber>",
        "entityId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "entityName": "<entityName>",
        "lastModifiedDate": "2026-01-15T09:30:00.000Z",
        "lines": [
          {
            "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "lineNumber": "<lineNumber>",
            "description": "<description>",
            "taxableBasis": "19.99",
            "taxAmount": "19.99",
            "totalAmount": "19.99"
          }
        ]
      }
    ],
    "pagination": {
      "nextCursor": "<nextCursor>",
      "hasMore": true
    }
  },
  "diagnostics": [
    {
      "code": "<code>",
      "message": "<message>",
      "severity": "error",
      "path": [
        "<path>"
      ],
      "details": "<details>"
    }
  ]
}
```

## Errors

| Code | Status |
| --- | --- |
| `INVALID_DATE` | 400 |
| `INVALID_TIMESTAMP` | 400 |

## Statuses

- `400` — Invalid request or business failure. Codes: INVALID_DATE, INVALID_TIMESTAMP
- `401` — The request carries no valid access token.
- `403` — Not authorized
- `404` — Not found
- `429` — Too many requests from this client address. The response has no body and no `Retry-After` header.
- `500` — Internal server error
