> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pylon.mortgage/llms.txt
> Use this file to discover all available pages before exploring further.

# Node query (global object identification)

> Fetch any object by ID with the node root field. Use it to build open-by-ID search (e.g. Cmd+X), efficient polling, deep links, and list-to-detail in Pylon.

The Pylon GraphQL API exposes a **`node`** root field that lets you fetch any object by its globally unique **`id`**. When your integration has an ID (from your app’s search (e.g. Cmd+X), a URL, a list, or a mutation), `node(id)` is a single way to load the full entity without choosing the right root query (`loan`, `borrower`, `asset`, etc.). That makes building a global “open by ID” and efficient polling much simpler. This follows the [Global Object Identification](https://graphql.org/learn/global-object-identification/) pattern.

## What the node query is

The root **Query** has a field (described in the schema as “Get an entity by ID”):

```graphql theme={null}
node(id: ID!): Node!
```

* You pass a single **`id`** (the same `id` value returned on any entity, e.g. from a previous query or mutation).
* The server returns the object that has that ID. The return type is non-null (**`Node!`**); if the entity does not exist or you don’t have access, the API typically returns an error rather than `null`.

The return type **`Node`** is an interface (“An entity uniquely identified by its id field”) implemented by types such as **Loan**, **Borrower**, and **Asset** (and all asset subtypes, e.g. `CheckingAccountAsset`, `GiftAsset`). The concrete type is determined by the server based on the ID.

## Example: loading by ID

When you have an `id` (e.g. from a list of loans or borrowers, from a mutation response, or from the URL), you can load that entity without choosing the right root query (`loan`, `borrower`, `asset`):

```graphql theme={null}
query GetNode($id: ID!) {
  node(id: $id) {
    id
    ... on Loan {
      id
      currentStage
      loanAmount
    }
    ... on Borrower {
      id
      firstName
      lastName
    }
    ... on Asset {
      id
      amount
    }
  }
}
```

Use **inline fragments** (`... on Loan`, `... on Borrower`, `... on Asset`, etc.) to ask for fields that are specific to each type. The response will only populate the fragment that matches the actual type of the node. For asset subtypes (e.g. `CheckingAccountAsset`, `GiftAsset`), use `... on Asset` to request common fields, or a fragment on the concrete type for type-specific fields.

## What the node query is good for in Pylon

Use cases below are ordered by impact for typical Pylon integrations.

* **Powerful search (e.g. Cmd+X)**: You can build a global “open by ID” or quick-jump in your app: one search or “Open by ID” input where the user pastes or types a loan, borrower, or asset ID. Call `node(id)` with fragments for Loan, Borrower, and Asset; the response tells you what type it is and gives you the fields you need. One query, one input; no need to parse the ID or ask “Loan or Borrower?”. This is the highest-leverage use of the node query for daily workflow.

* **More efficient polling**: When you [poll for loan updates](/recipes/loan-updates) (stages, tasks, order-outs), you often have a list of IDs (e.g. `deal.loans[].id` or loans from a pipeline query). To refresh only what changed or to load detail for one item, use `node(id)` and request just the fields you need. One query shape for every entity type means less branching in code and, when refetching a single entity, a smaller payload than re-running a heavy `loan` or `deal` query. You can also poll a lightweight list query, then call `node(id)` only for the loans the user has open or that need updating.

* **Deep links and shareable URLs**: Use URLs like `/loan/abc123` so users can bookmark or share a loan. On load you have only the ID from the path. Call `node(id)` and use fragments to get the right fields; render the correct view from which fragment returns data. No need to encode entity type in the route.

* **List or pipeline to detail**: Lists from Pylon (loans by deal or stage, borrowers, assets) return items with an `id`. When the user clicks a row, you have the ID. One `node(id)` call loads the full entity for that row; same query whether the row is a loan, borrower, or asset.

* **Refetch after a mutation**: Mutations in the [e2e flow](/guides/getting-started/e2e-build) return an `id`. To show the full entity or refresh the UI, call `node(id)` with the fields you need. Same pattern for every type you create or update.

* **Normalized caching**: GraphQL clients (e.g. Apollo, Relay) that cache by `id` need one way to refetch any entity. The node query is that single entry point for all node types in Pylon, which fits [normalized cache](https://graphql.org/learn/global-object-identification/) and refetch-by-id.

## Behavior and limits

* **Stability**: For a given `id`, the server returns the same logical object; if the same `id` appears in multiple places in a response, they refer to the same entity.
* **Missing or inaccessible objects**: If the entity does not exist or you don’t have access, the API typically returns an error (the field is non-null `Node!`).
* **Fragments**: Always request at least one type-specific fragment (e.g. `... on Loan { ... }`) so you get useful fields; the shared `id` is always available on `Node`.

For the full specification and rationale, see [Global Object Identification](https://graphql.org/learn/global-object-identification/) on GraphQL.org.
