# Choosing an endpoint

[Open in the interactive reference](https://docs.api.lensing.ai/guides/jobs)

Many resources offer more than one way to do the same thing: a read by id, a collection and a search, and for some resources bulk writes or events.

The choice decides which filters you can use, whether you get list records or full records, and how many requests a job takes.

### Common jobs

Each row names the endpoint to call and the section with the detail.

| To | Call | See |
| --- | --- | --- |
| List or scan records | `GET /x` | [Pagination and querying](https://docs.api.lensing.ai/guides/pagination.html) |
| Find a record by its name or number | `POST /x/search` | [Reading records](https://docs.api.lensing.ai/guides/reading.html) |
| Download a file a record carries | `GET /public/files/{handle}` | [Files](https://docs.api.lensing.ai/guides/files.html) |
| Send a file, such as an attachment | `POST /public/files/{namespace}/{operationId}`, then the endpoint with the upload reference | [Files](https://docs.api.lensing.ai/guides/files.html) |
| Read a record another record points to, such as `customerId` | `GET /customers/{id}` as a second request. No endpoint can include related records. | [Reading records](https://docs.api.lensing.ai/guides/reading.html) |
| Sync the changes since your last run | `GET /x?filter[lastModifiedDate][gte]=…&sort=lastModifiedDate`. People absences and absence types don't return `lastModifiedDate`. Deleted records don't appear; see Deleted records. | [Pagination and querying](https://docs.api.lensing.ai/guides/pagination.html) |
| Export every record | A paging loop over `GET /x`. A walk ends after about 100,000 records, so narrow larger exports with a filter. | [Pagination and querying](https://docs.api.lensing.ai/guides/pagination.html) |
| Create or change a record, then check it | `POST` or `PATCH`, then `GET /x/{id}` | [Writes](https://docs.api.lensing.ai/guides/writes.html) |
| Create or delete many records at once | `POST /x/bulk` or `/bulk-delete`, where the resource has one. Inventory and some project endpoints do. | [Bulk writes](https://docs.api.lensing.ai/guides/bulk.html) |
| React to changes as they happen | Subscribe to events. Invoices, journal entries and people publish them. For other records, sync on a schedule. | [Webhooks](https://docs.api.lensing.ai/guides/webhooks.html) |
| Retry a write safely after a timeout | Send an `Idempotency-Key` header. Almost every write accepts it, and one that doesn't lists `IDEMPOTENCY_NOT_SUPPORTED`. | [Idempotency](https://docs.api.lensing.ai/guides/idempotency.html) |

### Reading: by id, the collection or search

Check the resource's endpoint list first. Many resources offer both a collection, `GET /x`, and a search, `POST /x/search`. When a resource has both, choose in this order:

1. **You know the id:** use `GET /x/{id}`.
2. **You match text, such as a name, email or number, or pass several values for one filter:** use `POST /x/search`. Its filters travel in the request body.
3. **You list or sync records, filtering on ids, statuses or dates:** use `GET /x`.
4. **Still unsure:** use search. It returns full records, and its filters sit in the body rather than the query string.

### Collections that page differently

Twelve collections don't follow [Pagination and querying](https://docs.api.lensing.ai/guides/pagination.html). They take `pageSize` and a cursor as plain query parameters, return the records in `data.items`, and ignore `page[…]`, `filter[…]`, `sort` and `fields` without an error. Each one's description says so.

| Collection | Cursor | Changed since |
| --- | --- | --- |
| `GET crm/opportunities`, `crm/prospects`, `crm/quotes` | `cursor` | `modifiedFrom`, `modifiedTo` |
| `GET accounting/refunds`, `accounting/sales-order-shipments` | `cursor` | `modifiedFrom`, `modifiedTo` |
| `GET accounting/usages` | `cursor` | `lastModifiedFrom` |
| `GET accounting/performance-obligations/{id}/products` | `cursor` | — |
| `GET accounting/books/{bookId}/entity-assignments` | `page` | — |
| `GET base/custom-dimensions`, `base/custom-dimensions/{customDimensionUuid}/values` | `cursor` | — |
| `GET psa/expenses/budgets` | `cursor` | — |
| `GET psa/expenses/summary` | `pageCursor` | — |

## Examples

**Which read to use**

```
GET  /accounting/customers/{id}     id known
POST /accounting/customers/search   a name, or several values
GET  /accounting/customers          ids, statuses or dates
```
