Build

Placements

Create, update, and view lender placements in the Lev API.

Updated May 2026
GET/api/external/v2/placements
GET/api/external/v2/placements/{placement_id}
POST/api/external/v2/placements
PATCH/api/external/v2/placements/{placement_id}

Overview

Placements connect deals to lenders. Each placement has a status that tracks the lender's progression (e.g. sent, lender_reviewing, terms_received, closed).

EndpointDescription
GET /placementsList placements with filtering and pagination
GET /placements/{id}Get a single placement
POST /placementsCreate a placement against a deal
PATCH /placements/{id}Update a placement (use status="archived" to remove)

Placements do not have a DELETE verb. To remove a placement, send PATCH with status="archived". deal_id, private_company_id, and contact_id are set at create time and cannot be reassigned — archive the placement and create a new one to change linkage.

List Placements

GET/api/external/v2/placements

List placements with pagination

Query parameters
limitinteger
Results per page (1–200, default 50)
cursorstring
Cursor for next page

Response (200):

{
  "request_id": "c5d6e7f8-a9b0-1234-8901-345678901234",
  "timestamp": "2026-03-20T15:30:45Z",
  "data": [
    {
      "id": 310,
      "deal_id": 101,
      "private_company_id": 12,
      "contact_id": 78,
      "status": "lender_reviewing",
      "lender_status": "lead_qualification",
      "lev_score": 87.5,
      "score": 4.0,
      "description": "Strong fit — lender actively lending on multifamily in this submarket",
      "outreach_date": "2026-02-01",
      "outreach_source": "direct",
      "last_communication_date": "2026-03-15T10:00:00Z",
      "lender_first_response_date": "2026-02-03T09:30:00Z",
      "visibility": "shared",
      "created_at": "2026-02-01T08:00:00Z",
      "updated_at": "2026-03-15T10:00:00Z"
    }
  ],
  "pagination": {
    "total": 8,
    "limit": 50,
    "has_more": false,
    "next_cursor": null
  }
}
401unauthorized
Authentication requiredMissing or invalid Authorization header
400bad_request
cursor and sort cannot be combined; use offset pagination when sortingBoth cursor and sort params provided

Get Placement

GET/api/external/v2/placements/{placement_id}

Get a single placement by ID

Path parameters
placement_idintegerrequired
The placement ID

Response (200):

{
  "request_id": "d6e7f8a9-b0c1-2345-9012-456789012345",
  "timestamp": "2026-03-20T15:30:45Z",
  "data": {
    "id": 310,
    "deal_id": 101,
    "private_company_id": 12,
    "contact_id": 78,
    "status": "lender_reviewing",
    "lender_status": "lead_qualification",
    "lev_score": 87.5,
    "score": 4.0,
    "description": "Strong fit — lender actively lending on multifamily in this submarket",
    "outreach_date": "2026-02-01",
    "outreach_source": "direct",
    "last_communication_date": "2026-03-15T10:00:00Z",
    "lender_first_response_date": "2026-02-03T09:30:00Z",
    "visibility": "shared",
    "created_at": "2026-02-01T08:00:00Z",
    "updated_at": "2026-03-15T10:00:00Z"
  }
}
401unauthorized
Authentication requiredMissing or invalid Authorization header
404not_found
Placement not foundThe ID doesn't exist or isn't accessible to the authenticated user

Create Placement

POST/api/external/v2/placements

Create a placement against a deal

Supports the Idempotency-Key header to prevent duplicate creation. Requires the placements:write scope.

Request body
deal_idintegerrequired
ID of the deal this placement belongs to
private_company_idintegerrequired
ID of the lender private company (use `GET /companies` to find candidates)
contact_idinteger
ID of the lender contact for this outreach. Must belong to the lender at `private_company_id`
statusstring
Placement status enum name. Defaults to `new`. Cannot be `archived` on create
visibilitystring
Placement visibility (`hidden`, `masked`, `shared`)
descriptionstring
Free-text note (e.g. lender-specific feedback)
scorenumber
Manual relevance score (0–100)
outreach_datestring
ISO 8601 timestamp the lender was first contacted
lender_statusstring
Lender-side status enum name

Status enum values

new, sent, lender_reviewing, terms_received, term_sheet_received, executed_ts_in_closing, closed, unresponsive, willing_to_negotiate, lender_passed, carve_out, carve_out_closed. archived is reserved for Update Placement and cannot be used on create.

Lender status enum values

origination, new, lead_qualification, quotation, negotiation, offer, term_sheet, good_faith_deposit, diligence, in_closing, closed, archived.

curl -X POST "https://api.lev.com/api/external/v2/placements" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{
    "deal_id": 101,
    "private_company_id": 12,
    "contact_id": 78,
    "status": "sent",
    "description": "Strong fit — initial outreach via direct intro"
  }'

Response (201):

{
  "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "timestamp": "2026-05-19T15:30:45Z",
  "data": {
    "id": 311,
    "deal_id": 101,
    "private_company_id": 12,
    "contact_id": 78,
    "status": "sent",
    "lender_status": null,
    "lev_score": null,
    "score": null,
    "description": "Strong fit — initial outreach via direct intro",
    "outreach_date": null,
    "outreach_source": null,
    "last_communication_date": null,
    "lender_first_response_date": null,
    "visibility": "hidden",
    "created_at": "2026-05-19T15:30:45Z",
    "updated_at": "2026-05-19T15:30:45Z"
  }
}
400bad_request
Cannot create a placement with status='archived'; create an active placement and PATCH to archiveRequest body includes `status: "archived"`
400bad_request
A placement already exists for this deal, contact, and lender; use PATCH to update itAn active placement at this `(deal_id, contact_id)` pair already exists
401unauthorized
Authentication requiredMissing or invalid Authorization header
404not_found
Deal not found`deal_id` doesn't exist or isn't accessible to the authenticated user
404not_found
Private company not found`private_company_id` doesn't exist in the deal owner's account scope
404not_found
Contact not found`contact_id` doesn't exist, isn't a lender contact, or doesn't belong to the specified lender
422validation_error
status: input is not a valid enum memberUnknown enum value sent for `status`, `visibility`, or `lender_status`

Update Placement

PATCH/api/external/v2/placements/{placement_id}

Update a placement (partial update)

Supports the Idempotency-Key header. Requires the placements:write scope. Send only the fields you want to change — at least one body field is required.

Path parameters
placement_idintegerrequired
The placement ID
Request body
statusstring
Placement status enum name. Use `archived` to remove the placement
visibilitystring
Placement visibility (`hidden`, `masked`, `shared`)
descriptionstring
Free-text note
scorenumber
Manual relevance score (0–100)
outreach_datestring
ISO 8601 timestamp the lender was first contacted
lender_statusstring
Lender-side status enum name

deal_id, private_company_id, and contact_id are not editable. To move a placement to a different lender or contact, archive this placement (status: "archived") and create a new one.

Archiving: sending status: "archived" clears contact_id, sets visibility: "hidden", and removes the placement from list and detail reads. Other fields sent alongside (e.g. a final description) still apply.

curl -X PATCH "https://api.lev.com/api/external/v2/placements/311" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "lender_reviewing",
    "description": "Lender confirmed receipt and is reviewing rent roll"
  }'

Response (200):

{
  "request_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "timestamp": "2026-05-19T15:30:45Z",
  "data": {
    "id": 311,
    "deal_id": 101,
    "private_company_id": 12,
    "contact_id": 78,
    "status": "lender_reviewing",
    "lender_status": null,
    "lev_score": null,
    "score": null,
    "description": "Lender confirmed receipt and is reviewing rent roll",
    "outreach_date": null,
    "outreach_source": null,
    "last_communication_date": "2026-05-19T15:30:45Z",
    "lender_first_response_date": null,
    "visibility": "hidden",
    "created_at": "2026-05-19T15:30:45Z",
    "updated_at": "2026-05-19T15:30:45Z"
  }
}
400bad_request
Request body must contain at least one field to updateEmpty request body
401unauthorized
Authentication requiredMissing or invalid Authorization header
404not_found
Placement not found`placement_id` doesn't exist or isn't accessible to the authenticated user
422validation_error
status: input is not a valid enum memberUnknown enum value sent for `status`, `visibility`, or `lender_status`

Placement Object

FieldTypeDescription
idintegerPlacement identifier
deal_idintegerAssociated deal ID
private_company_idinteger|nullLender private company ID
contact_idinteger|nullLender contact ID
statusstring|nullCurrent placement status
lender_statusstring|nullLender-side status
descriptionstring|nullPlacement description
lev_scorenumber|nullAI-generated match score
scorenumber|nullManual score
outreach_datestring|nullDate of initial outreach
outreach_sourcestring|nullSource of outreach
last_communication_datestring|nullDate of last communication
lender_first_response_datestring|nullDate of lender's first response
visibilitystring|nullPlacement visibility
created_atstring|nullCreation timestamp
updated_atstring|nullLast update timestamp
More in this section