ClickCease

Leni HTTP API

Run Leni analysis

Start a real-estate or finance analysis with optional session context, memory, and attachments.

POST/users/run-models

FieldTypeRequirementBehavior
questionstringRequiredNon-empty prompt to answer.
sessionIdUUIDOptionalReuse the returned session id on follow-up requests to preserve history.
tonestringOptionalprofessional, friendly, authoritative, consultative, or funny. Defaults to professional.
fastModebooleanOptionalRequests the faster upstream path when supported. Defaults to false.
waitboolean or "true"OptionalWait for a complete response when the run stays synchronous. A durably admitted async run still returns HTTP 202.
user.modelTypestringOptionalModel selection such as leniq-pro. User and organization identity still come from the API key.
user.modelIdstringOptionalAuthorized custom model identifier when applicable.
customAnalystobjectOptionalAn owned custom analyst selection.
files / filesBase64arrayOptionalBase64 file objects. Multipart parts named files are also supported.
uploadedAttachmentsarrayOptionalMetadata for previously stored attachments.
userMemoryAttachmentsIdsstring[]OptionalOwned user-memory attachment ids to include.
orgMemoryAttachmentsIdsstring[]OptionalAuthorized organization-memory attachment ids to include.
taggedMemoryIdsarrayOptionalReferenced memory items; attachment ids may be derived from these entries.

Owner context

The project-key owner and active organization always win over identity fields in the body. Only select models, memory, and attachments the owner is authorized to use.

Accepted async response (HTTP 202)

Async-capable analysis is durably admitted before this response is returned. Save the exact run, message, and session identifiers. Once accepted is true, do not repeat the POST; poll the existing run instead. A message or analysis identifier is not a session identifier.

{
  "accepted": true,
  "status": "processing",
  "runId": "<uuid>",
  "messageId": "<uuid>",
  "sessionId": "<uuid>",
  "responseDeadlineReached": true,
  "pollAfterSeconds": 2,
  "hint": "The analysis was accepted and is still running. ..."
}

Poll the exact accepted message

Wait at least pollAfterSeconds, then call GET /users/me/chat-messages/:messageId with the returned messageId. Continue while its status is processing. On completed or failed, fetch the persisted result with POST /users/me/chat-sessions/message-responses using the same sessionId and messageId.
Message statusMeaningClient action
processingThe admitted run is queued or executing.Keep polling with backoff.
completedThe terminal response was persisted successfully.Fetch the message response.
failedThe run reached a terminal failure.Fetch the response for failure detail; do not clone or use an older result.

Completed response (HTTP 200)

A synchronous completion returns HTTP 200. Set wait: true only when the caller can hold the HTTP connection, but do not assume it forces synchronous execution: a durably admitted run still returns the HTTP 202 shape above. A completed normalized response can include messageId, sessionId, quickReply, reasoning, result, success, summary, and generated-file attachments.

curl -sS -X POST "https://api.prod.ca-central-1.leni.co/users/run-models" \
  -H "X-Api-Key: $LENI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Summarize portfolio occupancy drivers.",
    "user": { "modelType": "leniq-pro" },
    "tone": "professional",
    "wait": false
  }'

Follow-up prompts must reuse sessionId. runId identifies durable execution only;messageId identifies the turn to poll and retrieve; sessionId identifies conversation context. Never substitute one for another.

Synchronous deadline compatibility

If an analysis uses the synchronous fallback and exceeds the gateway’s roughly five-second response deadline, the API can return HTTP 200 with responseDeadlineReached: true, messageId, and sessionId. Poll it with the same lifecycle above.