> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.defdex.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.defdex.io/_mcp/server.

# Entity lookup and relationships

Read an entity directly by UUID or slug, then traverse explicitly published relationships.
These operations require `data:read` and share normal account usage limits.

## Resolve an entity

`GET /api/v1/entities/{collection}/{identifier}` returns `{data, build_id}`, where
`data` contains `record_id` and `attributes`.

Supported collections: `organizations`, `agencies`, `programs`, `technologies`,
`systems`, `sources`. UUID-shaped identifiers default to `by=id`; others default to
`by=slug`. Set `by` explicitly for a UUID-shaped slug. Sources support UUID only.
Agencies are constrained to organizations with `type = agency`.

```text
GET /api/v1/entities/organizations/EXACT_PUBLISHED_SLUG
GET /api/v1/entities/programs/RETURNED_UUID?by=id
GET /api/v1/entities/organizations/EXTERNAL_VALUE?by=external&scheme=EXACT_SCHEME
```

External lookup is supported for organizations/agencies using exact `scheme` and
`value` from `organization-identifiers`; use the actual published scheme spelling.
An unmatched identity returns 404. Ambiguous matches return 409 instead of silently
choosing a candidate. URL-encode the identifier as one segment.

## Traverse relationships

`GET /entities/{collection}/{identifier}/{relationship}` returns a normal record page
plus `dataset`, `relationship` and the resolved `parent_id`. Some relationships return
link rows; resolve their foreign keys through entity lookup or dataset filters.

| Parent collection | Relationship → target dataset / parent field                                                                                                                                                                                                           |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `organizations`   | `awards` → awards / recipient_id; `programs` → program-participants / organization_id; `technologies` → organization-technologies / organization_id; `systems` → systems / organization_id; `identifiers` → organization-identifiers / organization_id |
| `agencies`        | `programs` → programs / agency_id; `awards` → awards / awarding_agency_id; `funded-awards` → awards / funding_agency_id                                                                                                                                |
| `programs`        | `participants` → program-participants / program_id; `awards` → awards / program_id; `systems` → program-systems / program_id; `obligations` → program-obligations / program_id                                                                         |
| `technologies`    | `organizations` → organization-technologies / technology_id; `systems` → system-technologies / technology_id                                                                                                                                           |
| `systems`         | `technologies` → system-technologies / system_id; `inputs` → system-inputs / system_id                                                                                                                                                                 |

Unknown relationships return 404. Missing parents return 404; a found parent with no
related rows returns an empty successful page. The server supplies the parent filter;
callers cannot override it. Organization awards here are **direct recipient** awards,
not the ultimate-parent convenience award filter. Relationship coverage remains limited
to published links, not inferred associations.

Pass `limit`, `cursor`, `q`, `filters`, `where` and `sort` according to the target
dataset's rules. Keep parent identity and query unchanged while paging. Entity and child
reads must observe the same build; otherwise the request returns 409. Each database
query retains its five-second budget; resolution may perform multiple queries.

## Clients (0.1.2+)

```javascript
const organization = await api.entity('organizations', 'EXACT_PUBLISHED_SLUG');
const related = await api.related('organizations', organization.data.attributes.id,
  'awards', {where: {obligated_usd: {gte: '1000000.00'}}, limit: 25});
```

Python: `api.entity(collection, identifier, by=..., scheme=...)` and
`api.related(collection, identifier, relationship, limit=..., filters=..., where=..., sort=...)`.
CLI: `defdex entity organizations EXACT_PUBLISHED_SLUG` and
`defdex related agencies EXACT_PUBLISHED_SLUG programs --limit 25`.
MCP: `get_entity` and `get_related_records` use the same named inputs. Generic
`search_records` also supports `where` and `sort`.