---
key: api-record-identity
title: How records are identified
audience: developer
section: api/getting-started
routes: []
since: 0.0.1
updated: 0.0.1
status: published
summary: Every Nova record has an opaque uid for software and a record number for people. Which to send, which to show, and the few identifiers that are not records.
keywords: [uid, id, identifier, record number, ACC-, prefix, primary key, legacy, recurrence]
related: [api-conventions, api-errors, find-what-to-call]
---

A Nova record has two names you will meet, and each has one job.

| Name | Example | Use it for |
|---|---|---|
| `uid` | `acct_a1b2c3d4e5f6a1b2` | Every path, body, query filter, webhook and link |
| Record number | `ACC-000042` | Showing to people and searching; never for addressing |

There is no third, numeric id on the wire. If you see a bare number where a
record should be, it is a scoping value (below), not a record.

## Uids

- The prefix names the record type: `acct_` an account, `cdoc_` a quote or
  invoice, `work_order_` a work order, `task_` a task, and so on. Treat the whole value as opaque;
  do not build one or assume its length.
- A uid of the wrong type returns `404`, never `422`: handing an invoice uid
  to an account route looks exactly like a missing account.
- Uids never change. Store them.

```bash
curl -s https://app.novabmp.com/v1/crm/accounts/acct_5f1c2a9e7b3d4c10/ \
  -H "Authorization: Bearer $NOVA_KEY"
```

## Fields that end in `_id`

Some request fields are named `account_id`, `work_order_id` and so on. They
take the **uid**:

```json
{"title": "Call Smith about the furnace filter",
 "account_id": "acct_5f1c2a9e7b3d4c10"}
```

Statement generation, previews and regeneration take the customer uid in
`source_account_id` too.

Statement snapshots, activity, delivery metadata and job summaries also use
uids for related records. Activity rows carry `ledger_entry_uid`; job scopes
carry `statement_uids` and `effective_account_uids`. The snapshot's amounts,
record numbers and transaction order stay as recorded. Missing historical
references are `null`. Statement-list exports use `source_account_uid`,
`effective_account_uid`, `payer_account_uid`, `current_version_uid` and
`included_account_uids` for their linked records.

Agreement subject links return `subject_uid`. A subject without a registered
record type uses a synthetic `legacy:<n>` reference; treat it as an opaque string.
Uploaded-PDF preview metadata identifies its file with `file_uid`.
Media Center locations use `reference_uid` for the canonical attachment or
media record and `entity_uid` for its owner, including archived references.
Custom-field change events identify the value with its own uid, alongside the
field uid and the uid of the record that holds the value.

Payment allocations return `financial_document_uid` and `source_document_uid`.
Booking and work-order line items return the `offering_uid`, `inventory_item_uid`,
`inventory_asset_uid`, `inventory_unit_uid` and service-asset uid fields for linked
records. Their corresponding integer fields are internal only.
Workforce tracking returns `resource_uid` for a schedule resource and
`current_schedule_linked` to indicate a provider link. Use the opaque
`active_schedule_ref`, `next_schedule_ref` and `scheduled_schedule_ref` fields
for schedule navigation. Offerings identify their branch with `branch_id`.

Accounting responses identify a linked source with `source_uid`, alongside
`source_type`. Journal lines use `entity_uid` for the account or vendor they
reference. A purchase-order receipt cost layer points back to the purchase
order and its line through `source_uid` and `source_line_uid`. An unavailable
reference is `null`; never substitute a database number. Asset report exports
also use uid columns for linked records.

Timekeeping events identify the entry, time sheet or export job by uid. Time
entry and time-sheet exports use uid columns for related records; the default
cost-center code includes the customer's uid. Clock-in and clock-out location
checks return `site_location_uid` for the job site.

Stock transactions return `reference_uid` for their source record. To link a
transaction to a source, send that uid in `reference_id` and its record kind
in `reference_type`. A uid of a different record kind is refused.
Transaction metadata uses `count_line_uid` or `transfer_line_uid` when the
source is an inventory count or transfer line.

Asset telemetry webhooks carry related record references in `data.references`.
The shared webhook envelope carries `actor` and `subject` at its top level;
there is only one `data` object. Linked assets, sources, devices and signal
records use uids.

## Scoping values

`branch_id` (with `branch_uid` and `branch_name` beside it on responses) and
the `X-Organization-ID` header are small numbers that scope a request. They
are not records and are the one place a number is expected. Machine
credentials are bound to one organization and do not send the header.

## Identifiers that are not a single record

On the Schedule, a row can be a projection rather than a stored record:

- `legacy:<n>` — a row made before uids; read it, do not store it.
- `recur:<parent-uid>:<epoch>` — one occurrence of a repeating item. Change
  the occurrence through its parent.

## Read a record opened from a drawer

A browser can open a record detail without first loading its table. Use the record's opaque UID for these reads, with the same workspace and permissions as its list. File metadata reads enforce ordinary file access; ticket event reads additionally require the event to belong to the addressed ticket; owner activity reads require the addressed owner. Text-message details retain inbox and account visibility filters. Schedule waiting-item reads retain work-branch scope.

An address is a selection, not authorization or a command. Reading one must never repeat a send, payment, account-capture confirmation, credential rotation or other write. Private preview capabilities and one-time credentials remain outside the page address.
