/api/external/v2/deals/api/external/v2/deals/{deal_id}Structured deal detail/api/external/v2/deals/{deal_id}/index/searchCanonical indexed facts/api/external/v2/deals/{deal_id}/index/observationsSource values behind a fact/api/external/v2/deals/{deal_id}/index/factsChange a deal fact's canonical value/api/external/v2/deals/{deal_id}/index/metric-definitionsRecordable metric catalog/api/external/v2/deals/{deal_id}/index/entitiesEntities you can attach facts to/api/external/v2/deals/{deal_id}/index/factsRecord user-supplied metric values/api/external/v2/deals/{deal_id}/memosA deal's memos (published + draft)/api/external/v2/deals/{deal_id}/memos/{memo_uuid}One memo with signed PDF linksOverview
The deals endpoints support full CRUD operations with filtering, sorting, pagination, sparse fieldsets, and optional sub-resource includes.
| Endpoint | Description |
|---|---|
GET /deals | List deals with filtering and pagination |
GET /deals/{id} | Get a single deal |
POST /deals/{id}/index/search | Search canonical indexed facts and source provenance for a deal |
POST /deals/{id}/index/observations | List candidate observations (per-document extractions) behind a fact |
PATCH /deals/{id}/index/facts | Update a single canonical fact value (direct replacement or promote an observation) |
GET /deals/{id}/index/metric-definitions | List the metrics that can be recorded on a deal |
GET /deals/{id}/index/entities | List the entities (deal, properties, sponsor) you can attach facts to |
POST /deals/{id}/index/facts | Record one or more user-supplied metric values |
GET /deals/{id}/memos | List a deal's memos (deal books) — published and draft |
GET /deals/{id}/memos/{memo_uuid} | Fetch one memo with signed PDF download links |
POST /deals | Create a new deal |
PATCH /deals/{id} | Update a deal |
DELETE /deals/{id} | Archive (soft-delete) a deal |
List Deals
/api/external/v2/dealsList deals with pagination, filtering, and sorting
limitintegercursorstringoffsetintegersortstringfieldsstringincludestringfilter[loan_type]LoanTypefilter[transaction_type]TransactionTypefilter[business_plan]BusinessPlanTypefilter[loan_amount][gte]numberfilter[loan_amount][lte]numberfilter[created_at][gte]stringfilter[created_at][lte]stringcurl -X GET "https://api.lev.com/api/external/v2/deals?limit=10&include=financials&sort=-created_at" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "...",
"timestamp": "2026-03-20T15:30:45Z",
"data": [
{
"id": 101,
"title": "123 Main St Acquisition",
"loan_amount": 5000000.0,
"loan_type": "heavy_bridge",
"transaction_type": "acquisition",
"business_plan": "value_add",
"description": "Mixed-use acquisition in downtown",
"estimated_close_date": "2026-06-01",
"close_date": null,
"owner_account_id": 56,
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-03-10T14:30:00Z",
"financials": {
"id": 201,
"noi": 450000.0,
"purchase_price": 6500000.0,
"appraised_value": 7000000.0,
"ltv": 0.714,
"dscr": 1.25
}
}
],
"pagination": {
"total": 42,
"limit": 10,
"offset": 0,
"has_more": true
}
}unauthorizedbad_requestGet Deal
/api/external/v2/deals/{deal_id}Get a single deal by ID
deal_idintegerrequiredincludestringfieldsstringResponse (200):
{
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"id": 101,
"title": "123 Main St Acquisition",
"loan_amount": 5000000.0,
"loan_type": "heavy_bridge",
"transaction_type": "acquisition",
"business_plan": "value_add",
"description": "Mixed-use acquisition in downtown Chicago",
"estimated_close_date": "2026-06-01",
"close_date": null,
"owner_account_id": 56,
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-03-10T14:30:00Z"
}
}unauthorizednot_foundSearch Index
/api/external/v2/deals/{deal_id}/index/searchSearch canonical indexed deal facts by natural-language context
Use Index search when you need source-backed facts that may live in deal attachments or normalized underwriting data. It complements GET /deals/{deal_id}: use GET /deals/{deal_id} for structured deal fields, then use Index search for targeted questions about metrics, loan terms, proceeds, rent roll, occupancy, sponsor background, valuations, capex, dates, and source documents.
The endpoint searches Metric SOT / Index data for one deal. It does not return an exhaustive full Index export.
deal_idintegerrequiredcontextstringrequiredmin_scorenumberlimitintegerinclude_signed_urlsbooleancurl -X POST "https://api.lev.com/api/external/v2/deals/101/index/search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"context": "in-place NOI and source documents",
"min_score": 0.3,
"limit": 5,
"include_signed_urls": false
}'Response (200):
{
"request_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"timestamp": "2026-05-06T15:30:45Z",
"data": [
{
"id": "1",
"sot_id": 1,
"metric_key": "deal_financials.in_place_noi",
"metric_id": 42,
"metric_label": "In-place NOI",
"value_text": "$1,250,000",
"value_type": "currency",
"context": "The appraisal reports trailing twelve month NOI.",
"summary": "In-place NOI is $1.25M based on the appraisal.",
"period_type": "point_in_time",
"period_value": null,
"entity_type": "deal",
"entity_id": null,
"entity_ref": "deal:123",
"group_ref": null,
"category_id": 5,
"category_label": "Deal Financials",
"needs_review": false,
"score": 0.87,
"source": {
"type": "document",
"document_id": 99,
"document_type": "appraisal",
"file_name": "appraisal.pdf",
"file_extension": ".pdf",
"pages": [3, 12],
"observation_count": 3,
"signed_url": null
}
}
],
"pagination": {
"total": 1,
"limit": 5,
"offset": 0,
"has_more": false
}
}When include_signed_urls=true, document-backed results may include source.signed_url. Signing failures are non-fatal: the result stays in the response with source.signed_url=null and a typed source.signed_url_error such as signing_failed, missing_document_id, or invalid_document_id.
validation_errorunauthorizednot_foundservice_unavailableIndex Observations
/api/external/v2/deals/{deal_id}/index/observationsList per-document candidate values behind a deal fact
Each canonical fact returned by Search Index may be backed by multiple observations — one per document our extractors pulled the value from. Use this endpoint to enumerate those observations after a search, then either:
- show the user where a value came from (file, page range, confidence), or
- pick an
observation_idto promote via Update Index Fact so the canonical value keeps its document provenance.
Provide either sot_id (preferred — scopes to the exact fact behind a single search result) or metric_id (broader — returns observations for that metric across entities, optionally scoped by entity_ref). At least one is required.
deal_idintegerrequiredsot_idstringmetric_idintegerentity_refstringpageintegerlimitintegerinclude_signed_urlsbooleancurl -X POST "https://api.lev.com/api/external/v2/deals/101/index/observations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sot_id": "d:5362",
"limit": 20,
"include_signed_urls": false
}'Response (200):
{
"request_id": "d4e5f6a7-b8c9-0123-defa-234567890123",
"timestamp": "2026-05-12T17:45:30Z",
"data": [
{
"id": 9012,
"metric_key": "deal_financials.in_place_noi",
"metric_id": 42,
"value_text": "$1,250,000",
"value_type": "currency",
"original_text": "In-place NOI of $1,250,000 as of T-12",
"context": "Page 3 of the appraisal reports trailing twelve month NOI.",
"summary": "In-place NOI is $1.25M based on the appraisal.",
"period_type": "point_in_time",
"period_value": null,
"entity_type": "deal",
"entity_id": null,
"entity_ref": "deal:101",
"group_ref": null,
"category_id": 5,
"confidence": 0.91,
"weight": 10,
"source": {
"type": "document",
"document_id": 99,
"document_type": "appraisal",
"file_name": "appraisal.pdf",
"file_extension": ".pdf",
"pages": [3],
"observation_count": 1,
"signed_url": null
}
}
],
"pagination": {
"total": 3,
"limit": 20,
"offset": 0,
"has_more": false
}
}When include_signed_urls=true, document-backed results may include source.signed_url. Signing failures are non-fatal and follow the same source.signed_url_error convention as Search Index.
validation_errorunauthorizednot_foundservice_unavailableUpdate Index Fact
/api/external/v2/deals/{deal_id}/index/factsUpdate a single canonical deal fact value
Use this to change the canonical value behind a fact returned by Search Index. Provide exactly one of:
value— a direct, user-supplied replacement. Strips document provenance.observation_id— promote an existing observation returned by Index Observations. Preferred when the user is choosing among extracted values, because the new canonical value keeps its source document, page range, and confidence.
Editability is enforced server-side. Some facts (for example most property-canonical fields and certain sponsor financials) cannot be changed through this endpoint and will return a 422 — even if a prior search result hinted otherwise. There is no version history: the last write wins.
deal_idintegerrequiredsot_idstringrequiredvaluestringobservation_idintegercurl -X PATCH "https://api.lev.com/api/external/v2/deals/101/index/facts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sot_id": "d:5362",
"observation_id": 9012
}'Response (200):
{
"request_id": "e5f6a7b8-c9d0-1234-efab-345678901234",
"timestamp": "2026-05-12T17:50:12Z",
"data": {
"id": "5362",
"sot_id": 5362,
"metric_key": "deal_financials.in_place_noi",
"metric_id": 42,
"value_text": "$1,250,000",
"value_type": "currency",
"period_type": "point_in_time",
"period_value": null,
"entity_type": "deal",
"entity_id": null,
"entity_ref": "deal:101",
"group_ref": null,
"category_id": 5,
"source_type": "document",
"source_id": "99",
"observation_id": 9012,
"weight": 10,
"origin": "promoted_observation",
"editable": true
}
}validation_errorvalidation_errorunauthorizednot_foundservice_unavailableMetric Definitions
/api/external/v2/deals/{deal_id}/index/metric-definitionsList the metric definitions that can be recorded on a deal
Returns the catalog of metrics you can record on a deal — the metric_id and value_type you need when calling Insert Index Facts. Use it to discover what's recordable (for example NOI, occupancy, or purchase price) before writing a new fact. To change a fact a deal already has, prefer Search Index to find it, then Update Index Fact.
The catalog is shared across deals, not deal-specific — every deal sees the same definitions. Results are paginated and default to 100 per page.
deal_idintegerrequiredmetric_labelstringcategory_idintegerpageintegerlimitintegercurl "https://api.lev.com/api/external/v2/deals/101/index/metric-definitions?limit=100" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "f6a7b8c9-d0e1-2345-fabc-456789012345",
"timestamp": "2026-06-01T15:13:07Z",
"data": [
{
"id": 136,
"metric_key": "properties.property_financials.income.in_place_noi",
"metric_label": "In-Place NOI",
"value_type": "currency",
"category_id": 38
}
],
"pagination": {
"total": 458,
"limit": 100,
"offset": 0,
"has_more": true
}
}validation_errorunauthorizednot_foundservice_unavailableIndex Entities
/api/external/v2/deals/{deal_id}/index/entitiesList the entities you can attach recorded facts to
Lists the deal's entities and their entity_ref values — the deal itself plus its properties, sponsor, broker, and team members. Pass an entity_ref to Insert Index Facts to target which entity a recorded value belongs to. The entity_ref must match the metric's entity type: a property metric such as in-place NOI is recorded against a property: ref, not the deal: ref.
This endpoint does not create entities. To add a new property, call Create Deal (properties) or Update Deal (add_properties) — an address is the minimum required field — then read this endpoint again for the new entity_ref.
deal_idintegerrequiredcurl "https://api.lev.com/api/external/v2/deals/101/index/entities" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "a7b8c9d0-e1f2-3456-abcd-567890123456",
"timestamp": "2026-06-01T15:13:07Z",
"data": [
{
"entity_ref": "deal:101",
"entity_type": "deal",
"entity_id": 101,
"group_ref": null,
"identifying_metrics": [
{
"metric_key": "deal.metadata.title",
"metric_label": "Title",
"value_text": "2727 Cedar Springs Road, Dallas, TX",
"support_multiple_values": false
}
]
},
{
"entity_ref": "property:690",
"entity_type": "property",
"entity_id": 690,
"group_ref": null,
"identifying_metrics": [
{
"metric_key": "properties.property_details.identification.address",
"metric_label": "Address",
"value_text": "2727 Cedar Springs Road, Dallas, TX",
"support_multiple_values": true
}
]
}
],
"pagination": {
"total": 2,
"limit": 2,
"offset": 0,
"has_more": false
}
}unauthorizednot_foundservice_unavailableInsert Index Facts
/api/external/v2/deals/{deal_id}/index/factsRecord one or more user-supplied metric values on a deal
This is the default write path for user-supplied metric values — including when you're replacing a value the deal already has. Each insert creates or reuses a user-input observation and promotes it as the canonical value when supported.
The flow has three steps: discover the metric with Metric Definitions, discover the target entity with Index Entities, then post one or more metric_id + value pairs. Provide an entity_ref that matches the metric's entity type — a property metric needs a property: ref. On a single-property deal the entity can be inferred, but sending the explicit entity_ref is recommended.
To correct one existing fact (for example, fixing the NOI to $1.25M), use Update Index Fact instead — it targets a specific sot_id directly.
deal_idintegerrequiredvaluesarrayrequiredvalues[].metric_idintegerrequiredvalues[].valuestringrequiredvalues[].entity_refstringvalues[].group_refstringcurl -X POST "https://api.lev.com/api/external/v2/deals/101/index/facts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"values": [
{
"metric_id": 136,
"value": "$1,250,000",
"entity_ref": "property:690"
}
]
}'Response (200):
results reports the outcome of each submitted value in request order; metric_sot_values aggregates the SOTs that were written. Each results[].sot has the same shape as a metric_sot_values entry.
{
"request_id": "955b958f-55d6-42cc-a0f8-c600ce69f517",
"timestamp": "2026-06-01T15:19:34Z",
"data": {
"success": true,
"error": null,
"metric_sot_values": [
{
"id": "a:136:property:690",
"sot_id": null,
"metric_key": "properties.property_financials.income.in_place_noi",
"metric_id": 136,
"value_text": "$1,250,000",
"value_type": "currency",
"period_type": "none",
"period_value": null,
"entity_type": "property",
"entity_id": 690,
"entity_ref": "property:690",
"group_ref": null,
"category_id": 38,
"source_type": "user_input",
"source_id": null,
"observation_id": 17194,
"weight": 100,
"origin": "user",
"editable": null
}
],
"results": [
{
"index": 0,
"metric_id": 136,
"success": true,
"error": null,
"sot": {
"id": "a:136:property:690",
"sot_id": null,
"metric_key": "properties.property_financials.income.in_place_noi",
"metric_id": 136,
"value_text": "$1,250,000",
"value_type": "currency",
"period_type": "none",
"period_value": null,
"entity_type": "property",
"entity_id": 690,
"entity_ref": "property:690",
"group_ref": null,
"category_id": 38,
"source_type": "user_input",
"source_id": null,
"observation_id": 17194,
"weight": 100,
"origin": "user",
"editable": null
}
}
]
}
}A request can partially or fully fail while still returning HTTP 200. Always check the top-level success and each results[].error. For example, recording a property metric against a deal: ref returns success: false, an Invalid entity_ref for metric entity type error on that item, and an empty metric_sot_values.
validation_errorvalidation_errorunauthorizednot_foundservice_unavailableList Memos
/api/external/v2/deals/{deal_id}/memosList a deal's generated memos (deal books)
Lists the memos — AI-generated deal books — for a deal. Returns both published memos and unpublished drafts, so you can support preview-your-own-work flows. Each row carries status (published or draft) and published_at to disambiguate. Published memos come first (most recently published), then drafts (most recently updated).
PDF download links are omitted here — fetch a single memo with Get Memo for signed pdf_url links. Each row's pdf_ready flag tells you whether a downloadable PDF has rendered yet.
deal_idintegerrequiredlimitintegeroffsetintegercurl "https://api.lev.com/api/external/v2/deals/101/memos" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "43f2c567-57e4-4fac-8044-b22e01ec562c",
"timestamp": "2026-06-02T17:25:28Z",
"data": [
{
"uuid": "f26c0055-b2d3-4ca1-b25e-0ce0bacd0d61",
"title": "Debt Financing Offering Memorandum",
"memo_type": "debt_financing_om",
"status": "published",
"published_at": "2026-05-27T20:21:26",
"pdf_generation_status": "completed",
"pdf_ready": true,
"memo_url": "https://memo.lev.com/acme/deals/101/memos/f26c0055-b2d3-4ca1-b25e-0ce0bacd0d61"
},
{
"uuid": "8452c954-eedc-44ab-afbd-d86a8b65d007",
"title": "Investment Sales Offering Memorandum (draft)",
"memo_type": "investment_sales",
"status": "draft",
"published_at": null,
"pdf_generation_status": null,
"pdf_ready": false,
"memo_url": "https://memo.lev.com/acme/deals/101/memos/8452c954-eedc-44ab-afbd-d86a8b65d007"
}
],
"pagination": {
"total": 2,
"limit": 50,
"offset": 0,
"has_more": false
}
}unauthorizednot_foundGet Memo
/api/external/v2/deals/{deal_id}/memos/{memo_uuid}Fetch one memo with signed PDF download links
Returns one memo — published or draft — with signed PDF links. pdf_url points at the variant named by quality (default original); pdf_versions lists every rendered variant.
pdf_url is null and pdf_versions is empty when the memo has no rendered variant — common for drafts that have never been previewed (pdf_ready: false).
deal_idintegerrequiredmemo_uuidstringrequiredqualitystringcurl "https://api.lev.com/api/external/v2/deals/101/memos/f26c0055-b2d3-4ca1-b25e-0ce0bacd0d61?quality=original" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "69628f7c-3577-407a-9816-fd90942381f9",
"timestamp": "2026-06-02T17:25:56Z",
"data": {
"uuid": "f26c0055-b2d3-4ca1-b25e-0ce0bacd0d61",
"title": "Debt Financing Offering Memorandum",
"memo_type": "debt_financing_om",
"status": "published",
"published_at": "2026-05-27T20:21:26",
"pdf_generation_status": "completed",
"pdf_ready": true,
"memo_url": "https://memo.lev.com/acme/deals/101/memos/f26c0055-b2d3-4ca1-b25e-0ce0bacd0d61",
"pdf_url": "https://…signed-s3-url…",
"pdf_versions": [
{ "quality": "original", "status": "completed", "pdf_url": "https://…signed-s3-url…" },
{ "quality": "high", "status": "completed", "pdf_url": "https://…signed-s3-url…" },
{ "quality": "medium", "status": "completed", "pdf_url": "https://…signed-s3-url…" },
{ "quality": "low", "status": "completed", "pdf_url": "https://…signed-s3-url…" }
]
}
}pdf_url (and each pdf_versions[].pdf_url) is a short-lived signed link. Fetch the memo when you need a fresh link rather than storing it, and don't display the raw URL.
validation_errorunauthorizednot_foundCreate Deal
/api/external/v2/dealsCreate a new deal
Supports the Idempotency-Key header to prevent duplicate creation.
titlestringrequiredloan_amountnumberloan_typeLoanTypetransaction_typeTransactionTypebusiness_planBusinessPlanTypedescriptionstringestimated_close_datestringpipeline_idsinteger[]curl -X POST "https://api.lev.com/api/external/v2/deals" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{
"title": "456 Oak Ave Refinance",
"loan_amount": 3500000,
"loan_type": "permanent",
"transaction_type": "refinance"
}'Response (201):
{
"request_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"id": 205,
"title": "456 Oak Ave Refinance",
"loan_amount": 3500000.0,
"loan_type": "permanent",
"transaction_type": "refinance",
"business_plan": null,
"description": null,
"estimated_close_date": null,
"close_date": null,
"owner_account_id": 56,
"created_at": "2026-03-20T15:30:45Z",
"updated_at": "2026-03-20T15:30:45Z"
}
}unauthorizedvalidation_errorUpdate Deal
/api/external/v2/deals/{deal_id}Update a deal (partial update)
deal_idintegerrequiredAll request body fields are optional. Only provided fields are updated.
titlestringloan_amountnumberloan_typeLoanTypetransaction_typeTransactionTypebusiness_planBusinessPlanTypedescriptionstringestimated_close_datestringResponse (200):
{
"request_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"id": 101,
"title": "123 Main St Acquisition",
"loan_amount": 7500000.0,
"loan_type": "heavy_bridge",
"transaction_type": "acquisition",
"business_plan": "value_add",
"description": "Mixed-use acquisition in downtown Chicago — updated loan amount",
"estimated_close_date": "2026-07-15",
"close_date": null,
"owner_account_id": 56,
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-03-20T15:30:45Z"
}
}unauthorizednot_foundDelete Deal
/api/external/v2/deals/{deal_id}Archive (soft-delete) a deal
deal_idintegerrequiredResponse (200):
{
"request_id": "...",
"timestamp": "2026-03-20T15:30:45Z",
"data": {
"deleted": true
}
}unauthorizednot_foundDeal Object
| Field | Type | Description |
|---|---|---|
id | integer | Unique deal identifier |
title | string|null | Deal title |
loan_amount | number|null | Requested loan amount |
loan_type | LoanType|null | Loan type enum name |
transaction_type | TransactionType|null | Transaction type enum name |
business_plan | BusinessPlanType|null | Business plan enum name |
description | string|null | Deal description |
estimated_close_date | string|null | Estimated close date (ISO 8601) |
close_date | string|null | Actual close date (ISO 8601) |
owner_account_id | integer|null | Owning account ID |
created_at | string|null | Creation timestamp (ISO 8601) |
updated_at | string|null | Last update timestamp (ISO 8601) |
financials | object|null | Included when ?include=financials (see Deal Financials) |
properties | array|null | Included when ?include=properties (see Deal Properties) |
team | array|null | Included when ?include=team (see Deal Team) |
pipelines | array|null | Included when ?include=pipelines. Up to 10 current pipeline rows per deal, each with pipeline_id, status_name, updated_at (see Pipelines) |