/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}/vaultsA deal's vaults — Resources and Deal Rooms/api/external/v2/deals/{deal_id}/documentsUploaded files across a deal's vaults/api/external/v2/deals/{deal_id}/documents/{document_id}Metadata for one uploaded file/api/external/v2/deals/{deal_id}/documents/{document_id}/downloadShort-lived signed file link/api/external/v2/deals/{deal_id}/checklistsDeal Room checklists with task status and attached file references/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 links/api/external/v2/deals/{deal_id}/notesNotes logged on a deal/api/external/v2/deals/{deal_id}/notes/api/external/v2/deals/{deal_id}/notes/{note_id}/api/external/v2/deals/{deal_id}/notes/{note_id}/api/external/v2/checklist-tasks/{task_id}/notesComments on a checklist task/api/external/v2/checklist-tasks/{task_id}/notes/api/external/v2/checklist-tasks/{task_id}/notes/{note_id}/api/external/v2/checklist-tasks/{task_id}/notes/{note_id}/api/external/v2/checklist-tasks/api/external/v2/checklist-tasks/{task_id}/api/external/v2/checklist-tasks/{task_id}/completeOverview
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}/vaults | List a deal's vaults — its Resources area and any shared Deal Rooms |
GET /deals/{id}/documents | List uploaded documents across all of a deal's vaults |
GET /deals/{id}/documents/{document_id} | Fetch one uploaded document's metadata |
GET /deals/{id}/documents/{document_id}/download | Fetch a short-lived signed download link for one uploaded document |
GET /deals/{id}/checklists | List each Deal Room's checklist — sections, tasks, document types, and task-linked files |
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 |
GET /deals/{id}/notes | List notes logged on a deal |
POST /deals/{id}/notes | Add a note to a deal |
PATCH /deals/{id}/notes/{note_id} | Edit a deal note |
DELETE /deals/{id}/notes/{note_id} | Delete a deal note |
GET /checklist-tasks/{id}/notes | List comments on a checklist task (borrower-portal comments) |
POST /checklist-tasks/{id}/notes | Add a comment to a checklist task |
PATCH /checklist-tasks/{id}/notes/{note_id} | Edit a checklist task comment |
DELETE /checklist-tasks/{id}/notes/{note_id} | Delete a checklist task comment |
POST /checklist-tasks | Create a checklist task — a document request or to-do on a deal |
PATCH /checklist-tasks/{id} | Update a checklist task — retitle, re-status, reassign, set a due date, or reopen |
POST /checklist-tasks/{id}/complete | Mark a checklist task complete (also approves its attached files) |
POST /deals | Create a new deal, optionally with deal-level financials |
PATCH /deals/{id} | Update deal fields and writable deal-level financials |
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[archived]booleanfilter[loan_amount][gte]numberfilter[loan_amount][lte]numberfilter[created_at][gte]stringfilter[created_at][lte]stringArchiving a deal sets its archived and archived_at fields. It does not rewrite the deal's pipeline status, so an archived deal can still report a live-looking stage such as Reaching Out To Lenders. To separate active deals from archived ones, read the archived field or filter with filter[archived]. Do not infer archived state from a stalled pipeline stage.
curl -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",
"archived": false,
"archived_at": null,
"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",
"archived": false,
"archived_at": null
}
}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 Vaults
/api/external/v2/deals/{deal_id}/vaultsList a deal's vaults — its private Resources area and any shared Deal Rooms
Lists the vaults on a deal. Every deal has one private Resources vault for its own working files, plus zero or more shared vaults — the Deal Rooms the borrower shares with other parties. Use this to see how a deal's documents are organized into rooms before browsing files with List Documents.
Each vault reports its document_count. Results are ordered Resources first, then the deal's primary Deal Room (is_default: true), then any other shared vaults.
deal_idintegerrequiredcurl "https://api.lev.com/api/external/v2/deals/101/vaults" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "5f3c2a1e-9b7d-4c2a-8f1e-2d6b0a4c7e91",
"timestamp": "2026-06-09T17:59:05Z",
"data": [
{
"id": 41,
"type": "resources",
"title": "Deal Resources",
"is_default": false,
"document_count": 3
},
{
"id": 42,
"type": "shared",
"title": "Deal Room",
"is_default": true,
"document_count": 2
},
{
"id": 57,
"type": "shared",
"title": "Closing",
"is_default": false,
"document_count": 4
}
],
"pagination": {
"total": 3,
"limit": 3,
"offset": 0,
"has_more": false
}
}The type is the structural category — resources or shared — and title carries the human name. Only the default shared vault is the deal's primary Deal Room; other shared vaults are user-named for their own purpose (a per-lender room, Closing, and so on), so present the title, not the raw type. Pass a vault's id as the vault_id query parameter on List Documents to browse just that one. See the Vault Object for the full field reference.
unauthorizedforbiddennot_foundList Documents
/api/external/v2/deals/{deal_id}/documentsList a deal's uploaded documents across all of its vaults
Lists files uploaded to the deal — across its private Resources vault and any shared Deal Rooms. This is the deal-document browse surface for rent rolls, appraisals, budgets, closing documents, and other uploaded files. It is separate from generated memos and deal books, which are returned by List Memos.
By default the listing spans every vault on the deal, and each document is tagged with the vault it lives in. A file shared into more than one vault appears once per vault. Pass vault_id to drill into a single vault — get the ids from List Vaults.
The list returns metadata only. It does not include signed download URLs. Fetch a single document with Get Document, then use Download Document when you need a fresh file link.
This endpoint supports search, extension, folder_id, and vault_id. It intentionally does not accept generic filter[...] parameters.
deal_idintegerrequiredlimitintegercursorstringsearchstringextensionstringfolder_idintegervault_idintegerfieldsstringcurl "https://api.lev.com/api/external/v2/deals/101/documents?limit=20&extension=pdf" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "7b61eb1f-33e8-4b10-8891-90c6e6f5e768",
"timestamp": "2026-06-08T15:45:12Z",
"data": [
{
"id": 17,
"file_name": "rent-roll.pdf",
"extension": "pdf",
"size_bytes": 98765,
"folder_path": "Financials/2024",
"uploaded_at": "2026-06-01T10:00:00",
"vault": { "id": 41, "type": "resources", "title": "Deal Resources" }
},
{
"id": 21,
"file_name": "appraisal.pdf",
"extension": "pdf",
"size_bytes": 1452200,
"folder_path": null,
"uploaded_at": "2026-06-03T14:18:27",
"vault": { "id": 42, "type": "shared", "title": "Deal Room" }
}
],
"pagination": {
"total": 2,
"limit": 20,
"cursor": null,
"has_more": false,
"next_cursor": null
}
}Each document carries a vault tag — the Vault Object (id, type, title) for the vault it lives in. An accessible deal with no documents returns an empty list, not a 404. Documents that are rejected during review are excluded from list, detail, and download responses.
unauthorizedforbiddennot_foundnot_foundvalidation_errorGet Document
/api/external/v2/deals/{deal_id}/documents/{document_id}Fetch metadata for one uploaded document
Returns one uploaded document's metadata, including the vault it lives in. The document_id is the id returned by List Documents. The document is resolved across all of the requested deal's vaults — its Resources vault and any Deal Rooms.
deal_idintegerrequireddocument_idintegerrequiredfieldsstringcurl "https://api.lev.com/api/external/v2/deals/101/documents/17" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "ae1df8ee-c7c9-4ed0-82d2-19c4ec042ac4",
"timestamp": "2026-06-08T15:46:18Z",
"data": {
"id": 17,
"file_name": "rent-roll.pdf",
"extension": "pdf",
"size_bytes": 98765,
"folder_path": "Financials/2024",
"uploaded_at": "2026-06-01T10:00:00",
"vault": { "id": 41, "type": "resources", "title": "Deal Resources" }
}
}unauthorizedforbiddennot_foundDownload Document
/api/external/v2/deals/{deal_id}/documents/{document_id}/downloadFetch a short-lived signed download link for one uploaded document
Returns a signed S3 download URL for one uploaded document. The document is resolved across all of the deal's vaults, and the API re-checks that it belongs to the requested deal before signing, so a document from another deal returns 404 even if the account owns both deals.
Signed URLs expire after about 15 minutes. Request a fresh download link when the user is ready to open the file, and store document IDs rather than signed URLs in your system.
deal_idintegerrequireddocument_idintegerrequiredcurl "https://api.lev.com/api/external/v2/deals/101/documents/17/download" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "9fe1bfe1-b5c5-4a5f-8c7d-2766cf67a607",
"timestamp": "2026-06-08T15:47:08Z",
"data": {
"file_name": "rent-roll.pdf",
"download_url": "https://signed-s3-url.example/rent-roll.pdf",
"expires_in": 900
}
}download_url is a short-lived bearer link to the file bytes. Fetch it when you need a fresh link, present it as a clickable file-name link, and avoid displaying the raw URL in chat or UI surfaces.
unauthorizedforbiddennot_foundList Checklists
/api/external/v2/deals/{deal_id}/checklistsList a deal's checklists — one per shared Deal Room, with sections, tasks, document types, and task-linked files
Lists the checklists on a deal: the items to collect, review, or complete in each Deal Room. Checklists live on the deal's shared vaults. Each Deal Room can carry one checklist, and a deal with several Deal Rooms can have several checklists. The deal's private Resources vault does not have a checklist. Results are ordered with the primary Deal Room's checklist first.
Use the task-level document_types array to see what type of document a request expects. Use the task-level files array to see which uploaded files are already linked to that task. A task with no files can still be complete if a user marked it complete manually, so use both files and the completion fields (status, is_completed) when reporting what is satisfied or outstanding.
deal_idintegerrequiredvault_idintegercurl "https://api.lev.com/api/external/v2/deals/101/checklists" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "fa8d1a1e-4e9a-4c82-b68e-44e8db5b3a0c",
"timestamp": "2026-06-15T18:04:22Z",
"data": [
{
"id": 11,
"vault": {
"id": 42,
"type": "shared",
"title": "Deal Room"
},
"sections": [
{
"id": 21,
"name": "Financials",
"position": 1,
"start_date": "2026-06-01",
"end_date": null,
"tasks": [
{
"id": 301,
"title": "Rent roll",
"description": "Trailing 12 months",
"status": "reviewing",
"is_completed": false,
"position": 1,
"due_date": "2026-07-01",
"role": "borrower",
"assignee": {
"id": 9,
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com"
},
"assigned_team": {
"id": 8256,
"type": "account",
"name": "Borrower Team"
},
"collaborators": [
{
"id": null,
"email": "outside@example.com"
}
],
"document_types": [
{
"id": 15,
"name": "Rent roll"
}
],
"files": [
{
"vault_resource_id": 6001,
"document_id": 901,
"name": "Rent roll.xlsx",
"origin": "auto_match"
}
],
"subtasks": []
}
]
}
],
"tasks": []
}
],
"pagination": {
"total": 1,
"limit": 1,
"offset": 0,
"has_more": false
}
}Sections and tasks come back in display order (position ascending), matching the checklist as it appears in Lev. See the Checklist Object, Checklist Section Object, and Checklist Task Object for the full field reference.
unauthorizedforbiddennot_foundList 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, plus updated_at (last-modified) and created_by ({id, name} — who made the memo). 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.
By default the listing spans every vault on the deal, and each memo is tagged with the vaults it lives in. A memo can sit in more than one vault. Pass vault_id to return only the memos in a single vault — get the ids from List Vaults.
Narrow the list server-side with search (a case-insensitive title substring) and the filter[title] (exact title), filter[status], filter[memo_type], and filter[pdf_ready] parameters. Filters compose, and pagination reflects the filtered set. There is no sort control — the published-first ordering is fixed.
deal_idintegerrequiredlimitintegeroffsetintegersearchstringfilter[title]stringfilter[status]stringfilter[memo_type]stringfilter[pdf_ready]booleanvault_idintegercurl "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",
"updated_at": "2026-05-28T14:03:11",
"created_by": { "id": 4012, "name": "Jordan Avery" },
"pdf_generation_status": "completed",
"pdf_ready": true,
"memo_url": "https://memo.lev.com/acme/deals/101/memos/f26c0055-b2d3-4ca1-b25e-0ce0bacd0d61",
"vaults": [
{ "id": 42, "type": "shared", "title": "Deal Room" },
{ "id": 57, "type": "shared", "title": "Closing" }
]
},
{
"uuid": "8452c954-eedc-44ab-afbd-d86a8b65d007",
"title": "Investment Sales Offering Memorandum (draft)",
"memo_type": "investment_sales",
"status": "draft",
"published_at": null,
"updated_at": "2026-06-01T09:12:40",
"created_by": { "id": 4012, "name": "Jordan Avery" },
"pdf_generation_status": null,
"pdf_ready": false,
"memo_url": "https://memo.lev.com/acme/deals/101/memos/8452c954-eedc-44ab-afbd-d86a8b65d007",
"vaults": []
}
],
"pagination": {
"total": 2,
"limit": 50,
"offset": 0,
"has_more": false
}
}Each memo carries a vaults array — the Vault Object (id, type, title) for every vault it belongs to. The set is scoped to the vaults your credential can see: a vault you can't access is left out, and a memo in no vault you can see returns vaults: [].
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).
The vaults array tags the memo with each Vault Object it belongs to — a memo can be in more than one. The set is scoped to the vaults your credential can see, so it is empty when the memo is in no vault you can access.
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",
"updated_at": "2026-05-28T14:03:11",
"created_by": { "id": 4012, "name": "Jordan Avery" },
"pdf_generation_status": "completed",
"pdf_ready": true,
"memo_url": "https://memo.lev.com/acme/deals/101/memos/f26c0055-b2d3-4ca1-b25e-0ce0bacd0d61",
"vaults": [
{ "id": 42, "type": "shared", "title": "Deal Room" },
{ "id": 57, "type": "shared", "title": "Closing" }
],
"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_foundList Deal Notes
/api/external/v2/deals/{deal_id}/notesList notes logged on a deal
Lists the free-text notes logged on a deal — call summaries, lender conversations, and other human-written commentary. Notes are returned oldest first; walk the next_cursor in the response to reach the most recent. Internal or private notes are never returned.
For underwriting facts and where a value came from, use the deal index (Search Index) — notes are commentary, not indexed facts.
deal_idintegerrequiredlimitintegercursorstringcurl "https://api.lev.com/api/external/v2/deals/101/notes" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "43f2c567-57e4-4fac-8044-b22e01ec562c",
"timestamp": "2026-06-08T17:25:28Z",
"data": [
{
"id": 7340,
"text": "Lender call went well — they're comfortable at 65% LTV, want updated rent roll.",
"created_by": {
"id": 88,
"name": "Dana Lender"
},
"created_at": "2026-06-08T10:00:00Z",
"updated_at": "2026-06-08T10:00:00Z"
}
],
"pagination": {
"total": 1,
"limit": 50,
"has_more": false,
"next_cursor": null
}
}unauthorizednot_foundCreate Deal Note
/api/external/v2/deals/{deal_id}/notesAdd a note to a deal
Logs a free-text note on a deal. The note is attributed to the API key's user and appears alongside notes written in the Lev web app. Simple HTML formatting is preserved; scripts and other unsafe markup are stripped.
Supports the Idempotency-Key header to prevent duplicate creation. Requires the deals:write scope.
deal_idintegerrequiredtextstringrequiredcurl -X POST "https://api.lev.com/api/external/v2/deals/101/notes" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"text": "Lender call went well — they want an updated rent roll."}'Response (201):
{
"request_id": "d0e1f2a3-b4c5-6789-3456-890123456789",
"timestamp": "2026-06-08T15:30:45Z",
"data": {
"id": 7340,
"text": "Lender call went well — they want an updated rent roll.",
"created_by": {
"id": 88,
"name": "Dana Lender"
},
"created_at": "2026-06-08T15:30:45Z",
"updated_at": "2026-06-08T15:30:45Z"
}
}unauthorizednot_foundvalidation_errorUpdate Deal Note
/api/external/v2/deals/{deal_id}/notes/{note_id}Edit a deal note
Replaces the text of a note logged on a deal. Requires the deals:write scope. Use the id returned by List Deal Notes or Create Deal Note as note_id.
Only notes the authenticated user created and can still write are editable. Notes on another deal, hidden or private notes, and notes the user does not own return 404 Not Found.
Supports the Idempotency-Key header to make retries safe.
deal_idintegerrequirednote_idintegerrequiredtextstringrequiredcurl -X PATCH "https://api.lev.com/api/external/v2/deals/101/notes/7340" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"text": "Lender call went well — they want an updated rent roll and trailing 12."}'Response (200):
{
"request_id": "90d7bfc2-ff5e-4b4e-9c77-7987957fd6a7",
"timestamp": "2026-06-19T15:30:45Z",
"data": {
"id": 7340,
"text": "Lender call went well — they want an updated rent roll and trailing 12.",
"created_by": {
"id": 88,
"name": "Dana Lender"
},
"created_at": "2026-06-08T15:30:45Z",
"updated_at": "2026-06-19T15:30:45Z"
}
}unauthorizednot_foundbad_requestvalidation_errorDelete Deal Note
/api/external/v2/deals/{deal_id}/notes/{note_id}Permanently delete a deal note
Permanently deletes a note logged on a deal. Requires the deals:write scope. Use the id returned by List Deal Notes or Create Deal Note as note_id.
Only notes the authenticated user created and can still write are deletable. Notes on another deal, hidden or private notes, and notes the user does not own return 404 Not Found.
deal_idintegerrequirednote_idintegerrequiredcurl -X DELETE "https://api.lev.com/api/external/v2/deals/101/notes/7340" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "2c23bb16-8a8c-4a20-8ec0-9af5f555c84c",
"timestamp": "2026-06-19T15:30:45Z",
"data": {
"deleted": true
}
}unauthorizednot_foundList Checklist Task Notes
/api/external/v2/checklist-tasks/{task_id}/notesList comments on a checklist task
Lists the comments on a checklist task — the borrower-portal "comments" that appear in the task's activity feed. A checklist task is a single diligence item (for example, a document request) inside a Deal Room checklist. These are the same comments your team and the borrower post in the portal: reading here returns that thread, and posting is equivalent to commenting on the item in the Lev web app.
Comments are returned oldest first; walk the next_cursor in the response to reach the most recent. Internal or private notes are never returned.
task_idintegerrequiredlimitintegercursorstringcurl "https://api.lev.com/api/external/v2/checklist-tasks/4821/notes" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "43f2c567-57e4-4fac-8044-b22e01ec562c",
"timestamp": "2026-06-08T17:25:28Z",
"data": [
{
"id": 9120,
"text": "Uploaded the latest rent roll — let me know if you also need the prior year.",
"created_by": {
"id": 88,
"name": "Dana Lender"
},
"created_at": "2026-06-08T10:00:00Z",
"updated_at": "2026-06-08T10:00:00Z"
}
],
"pagination": {
"total": 1,
"limit": 50,
"has_more": false,
"next_cursor": null
}
}unauthorizednot_foundCreate Checklist Task Note
/api/external/v2/checklist-tasks/{task_id}/notesAdd a comment to a checklist task
Posts a comment on a checklist task. The comment is attributed to the API key's user and is borrower-visible — it surfaces in the task's portal activity feed exactly like a comment typed there by you or the borrower. Simple HTML formatting is preserved; scripts and other unsafe markup are stripped.
Supports the Idempotency-Key header to prevent duplicate creation. Requires the checklists:write scope.
task_idintegerrequiredtextstringrequiredcurl -X POST "https://api.lev.com/api/external/v2/checklist-tasks/4821/notes" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"text": "Uploaded the latest rent roll — let me know if you also need the prior year."}'Response (201):
{
"request_id": "d0e1f2a3-b4c5-6789-3456-890123456789",
"timestamp": "2026-06-08T15:30:45Z",
"data": {
"id": 9120,
"text": "Uploaded the latest rent roll — let me know if you also need the prior year.",
"created_by": {
"id": 88,
"name": "Dana Lender"
},
"created_at": "2026-06-08T15:30:45Z",
"updated_at": "2026-06-08T15:30:45Z"
}
}unauthorizednot_foundvalidation_errorUpdate Checklist Task Note
/api/external/v2/checklist-tasks/{task_id}/notes/{note_id}Edit a checklist task comment
Replaces the text of a comment on a checklist task. Requires the checklists:write scope. Use the id returned by List Checklist Task Notes or Create Checklist Task Note as note_id.
Only comments the authenticated user created and can still write are editable. Comments on another checklist task, hidden or private comments, and comments the user does not own return 404 Not Found.
Supports the Idempotency-Key header to make retries safe.
task_idintegerrequirednote_idintegerrequiredtextstringrequiredcurl -X PATCH "https://api.lev.com/api/external/v2/checklist-tasks/4821/notes/9120" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"text": "Uploaded the latest rent roll and prior-year version."}'Response (200):
{
"request_id": "90d7bfc2-ff5e-4b4e-9c77-7987957fd6a7",
"timestamp": "2026-06-19T15:30:45Z",
"data": {
"id": 9120,
"text": "Uploaded the latest rent roll and prior-year version.",
"created_by": {
"id": 88,
"name": "Dana Lender"
},
"created_at": "2026-06-08T15:30:45Z",
"updated_at": "2026-06-19T15:30:45Z"
}
}unauthorizednot_foundbad_requestvalidation_errorDelete Checklist Task Note
/api/external/v2/checklist-tasks/{task_id}/notes/{note_id}Permanently delete a checklist task comment
Permanently deletes a comment on a checklist task. Requires the checklists:write scope. Use the id returned by List Checklist Task Notes or Create Checklist Task Note as note_id.
Only comments the authenticated user created and can still write are deletable. Comments on another checklist task, hidden or private comments, and comments the user does not own return 404 Not Found.
task_idintegerrequirednote_idintegerrequiredcurl -X DELETE "https://api.lev.com/api/external/v2/checklist-tasks/4821/notes/9120" \
-H "Authorization: Bearer YOUR_API_KEY"Response (200):
{
"request_id": "2c23bb16-8a8c-4a20-8ec0-9af5f555c84c",
"timestamp": "2026-06-19T15:30:45Z",
"data": {
"deleted": true
}
}unauthorizednot_foundCreate Checklist Task
/api/external/v2/checklist-tasksAdd a task to a deal's checklist
Creates a checklist task — a document request or to-do tracked on the deal, such as collecting the trailing-12 operating statements. Anchor the task under exactly one parent: provide one of section_id (inside a section), checklist_id (at the checklist root, outside any section), or parent_task_id (a subtask, one level deep). Get those ids from List Checklists.
Returns the created task in the same shape List Checklists returns. Requires the checklists:write scope. Supports the Idempotency-Key header to prevent duplicate creation.
titlestringrequiredsection_idintegerchecklist_idintegerparent_task_idintegerdescriptionstringstatusstringassigned_user_idintegerdue_datestringdocument_type_idsarraycurl -X POST "https://api.lev.com/api/external/v2/checklist-tasks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{
"title": "Trailing-12 operating statements",
"section_id": 21,
"description": "From the sponsor",
"due_date": "2026-07-15",
"document_type_ids": [15]
}'Response (201):
{
"request_id": "b1c2d3e4-f5a6-7890-1234-567890abcdef",
"timestamp": "2026-06-23T15:30:45Z",
"data": {
"id": 412,
"title": "Trailing-12 operating statements",
"description": "From the sponsor",
"status": "to_do",
"is_completed": false,
"position": 4,
"due_date": "2026-07-15",
"role": null,
"assignee": null,
"assigned_team": null,
"collaborators": [],
"document_types": [
{
"id": 15,
"name": "Operating statement"
}
],
"files": [],
"subtasks": []
}
}See the Checklist Task Object for the full field reference.
unauthorizedforbiddenvalidation_errornot_foundvalidation_errorUpdate Checklist Task
/api/external/v2/checklist-tasks/{task_id}Change a checklist task's fields
Edits an existing checklist task — retitle, re-status, reassign, set a due date, or reopen it. Get the task_id from List Checklists. Sends only the fields you provide; omitted fields are left unchanged. Send null for description, assigned_user_id, due_date, or document_type_ids to clear them.
To mark a task complete use Complete Checklist Task — it also approves the task's attached files. Here is_completed accepts false only, to reopen a completed task. Requires the checklists:write scope. Supports the Idempotency-Key header to make retries safe.
task_idintegerrequiredtitlestringdescriptionstring|nullstatusstringassigned_user_idinteger|nulldue_datestring|nullis_completedbooleandocument_type_idsarray|nullcurl -X PATCH "https://api.lev.com/api/external/v2/checklist-tasks/301" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"due_date": "2026-07-15", "assigned_user_id": 88}'Response (200):
{
"request_id": "c2d3e4f5-a6b7-8901-2345-678901bcdef0",
"timestamp": "2026-06-23T15:30:45Z",
"data": {
"id": 301,
"title": "Rent roll",
"description": "Trailing 12 months",
"status": "reviewing",
"is_completed": false,
"position": 1,
"due_date": "2026-07-15",
"role": "borrower",
"assignee": {
"id": 88,
"first_name": "Dana",
"last_name": "Lender",
"email": "dana@example.com"
},
"assigned_team": {
"id": 8256,
"type": "account",
"name": "Borrower Team"
},
"collaborators": [],
"document_types": [
{
"id": 15,
"name": "Rent roll"
}
],
"files": [],
"subtasks": []
}
}unauthorizedforbiddenvalidation_errornot_foundvalidation_errorComplete Checklist Task
/api/external/v2/checklist-tasks/{task_id}/completeMark a checklist task complete
Marks a checklist task done — the equivalent of checking it off in the deal's checklist. Completing also moves the task to approved status and approves any pending files already attached to it, matching the in-app action. Get the task_id from List Checklists.
The body is empty. The action is idempotent: completing an already-complete task leaves it complete. To reopen a completed task use Update Checklist Task with is_completed set to false. Requires the checklists:write scope. Supports the Idempotency-Key header to make retries safe.
task_idintegerrequiredcurl -X POST "https://api.lev.com/api/external/v2/checklist-tasks/301/complete" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000"Response (200):
{
"request_id": "d3e4f5a6-b7c8-9012-3456-789012cdef01",
"timestamp": "2026-06-23T15:30:45Z",
"data": {
"id": 301,
"title": "Rent roll",
"description": "Trailing 12 months",
"status": "approved",
"is_completed": true,
"position": 1,
"due_date": "2026-07-01",
"role": "borrower",
"assignee": {
"id": 88,
"first_name": "Dana",
"last_name": "Lender",
"email": "dana@example.com"
},
"assigned_team": {
"id": 8256,
"type": "account",
"name": "Borrower Team"
},
"collaborators": [],
"document_types": [
{
"id": 15,
"name": "Rent roll"
}
],
"files": [
{
"vault_resource_id": 6001,
"document_id": 901,
"name": "Rent roll.xlsx",
"origin": "manually_added"
}
],
"subtasks": []
}
}unauthorizedforbiddennot_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[]deal_financialsDealFinancialsWritecurl -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",
"deal_financials": {
"purchase_price": 5250000,
"estimated_value": 5900000,
"total_cost": 5500000
}
}'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",
"archived": false,
"archived_at": null
}
}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. For deal_financials, omitted nested fields are unchanged and explicit null clears an existing value.
titlestringloan_amountnumberloan_typeLoanTypetransaction_typeTransactionTypebusiness_planBusinessPlanTypedescriptionstringestimated_close_datestringdeal_financialsDealFinancialsWritecurl -X PATCH "https://api.lev.com/api/external/v2/deals/101" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"loan_amount": 7500000,
"deal_financials": {
"purchase_price": 6500000,
"estimated_value": null
}
}'Response (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",
"archived": false,
"archived_at": null
}
}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_foundDocument Object
| Field | Type | Description |
|---|---|---|
id | integer | Unique document identifier. Use this value in the document detail and download endpoints. |
file_name | string|null | Original file name. |
extension | string|null | File extension without the leading dot. |
size_bytes | integer|null | File size in bytes. May be null for older records whose size was not stored. |
folder_path | string|null | Slash-delimited path inside the vault, or null for files at the vault root. |
uploaded_at | string|null | Upload timestamp (ISO 8601). |
vault | DocumentVaultRef | The vault this document lives in — the compact id, type, title subset of the Vault Object (omits the list-only is_default and document_count). Always present, even under a sparse fields request. |
Vault Object
A vault is a container for a deal's documents. Returned by List Vaults, embedded as the vault tag on each Document Object, and listed in the vaults array on each memo (List Memos, Get Memo).
| Field | Type | Description |
|---|---|---|
id | integer | Unique vault identifier. Pass as vault_id on List Documents to browse just this vault. |
type | string | Structural category: resources (the deal's single private working vault) or shared (a vault the borrower can share with other parties). Present the title to users, not this raw value. |
title | string|null | Human-readable vault name — Deal Resources for the private vault; shared vaults carry names like Deal Room, Closing, or a per-lender room. |
is_default | boolean | true for the deal's primary Deal Room (its default shared vault). Returned by List Vaults; omitted from the embedded document vault tag. |
document_count | integer | Number of documents in the vault. Returned by List Vaults; omitted from the embedded document vault tag. |
Checklist Object
A checklist is the to-do and request list inside one Deal Room. Returned by List Checklists, one per shared vault.
| Field | Type | Description |
|---|---|---|
id | integer | Unique checklist identifier |
vault | ChecklistVaultRef | The Deal Room this checklist belongs to: id, type, and title. type is always shared; checklists do not live on the private Resources vault. |
sections | ChecklistSection[] | Ordered sections, each carrying its own tasks. See the Checklist Section Object. |
tasks | ChecklistTask[] | Root-level tasks that sit outside any section, in display order. See the Checklist Task Object. |
Checklist Section Object
| Field | Type | Description |
|---|---|---|
id | integer | Unique section identifier |
name | string | Section name |
position | integer | Display order inside the checklist |
start_date | string|null | Optional section start date (ISO 8601) |
end_date | string|null | Optional section end date (ISO 8601) |
tasks | ChecklistTask[] | The section's tasks in display order. See the Checklist Task Object. |
Checklist Task Object
| Field | Type | Description |
|---|---|---|
id | integer | Unique task identifier |
title | string | Task title |
description | string|null | Task description |
status | string | Review state: to_do, requested, reviewing, updates_needed, approved, or cancelled. |
is_completed | boolean | Separate done flag. A task can be approved but not marked complete. |
position | integer | Display order inside its section or root task list |
due_date | string|null | Due date (ISO 8601) |
role | string|null | Role responsible for the task, such as borrower or lender |
assignee | ChecklistAssignee|null | The Lev user assigned to the task, or null when unassigned. |
assigned_team | ChecklistAssignedTeam|null | The account, lender, or borrower team assigned to the task. name can be null for stale or out-of-scope team references. |
collaborators | ChecklistCollaborator[] | People looped into the task. Each carries id and email; id is null for external parties without a Lev account. |
document_types | ChecklistDocumentType[] | Expected document types for the request, such as Appraisal or Rent roll. |
files | ChecklistTaskFile[] | Uploaded files already linked to this task. Each file includes document_id, vault_resource_id, name, and origin. |
subtasks | ChecklistTask[] | Nested subtasks, one level deep, in the same task shape. |
Deal 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) |
archived | boolean | Whether the deal has been archived. Archiving is separate from pipeline status, so an archived deal keeps its last stage |
archived_at | string|null | When the deal was archived (ISO 8601), or null when active |
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) |