curl --request POST \
--url https://api.prophia.com/rest/v2/accounts/{accountId}/docs \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"leaseId": "<string>",
"presignedUrl": "<string>",
"filename": "<string>",
"title": "<string>"
}
'import requests
url = "https://api.prophia.com/rest/v2/accounts/{accountId}/docs"
payload = {
"leaseId": "<string>",
"presignedUrl": "<string>",
"filename": "<string>",
"title": "<string>"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
leaseId: '<string>',
presignedUrl: '<string>',
filename: '<string>',
title: '<string>'
})
};
fetch('https://api.prophia.com/rest/v2/accounts/{accountId}/docs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prophia.com/rest/v2/accounts/{accountId}/docs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'leaseId' => '<string>',
'presignedUrl' => '<string>',
'filename' => '<string>',
'title' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.prophia.com/rest/v2/accounts/{accountId}/docs"
payload := strings.NewReader("{\n \"leaseId\": \"<string>\",\n \"presignedUrl\": \"<string>\",\n \"filename\": \"<string>\",\n \"title\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.prophia.com/rest/v2/accounts/{accountId}/docs")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"leaseId\": \"<string>\",\n \"presignedUrl\": \"<string>\",\n \"filename\": \"<string>\",\n \"title\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prophia.com/rest/v2/accounts/{accountId}/docs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"leaseId\": \"<string>\",\n \"presignedUrl\": \"<string>\",\n \"filename\": \"<string>\",\n \"title\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"filename": "<string>",
"title": "<string>",
"numberOfPages": 123,
"docCategory": "Main Lease Agreement",
"createdAt": "2023-11-07T05:31:56Z",
"documentStatus": "<string>",
"splitStatus": "single",
"originalDocId": "<string>"
}{
"error": "Invalid Input",
"errorCode": "InvalidInput",
"message": "dba cannot be blank",
"status": "400 BAD_REQUEST",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "dba cannot be blank"
}{
"error": "JWT authentication is not supported. Use an API key."
}{
"error": "Access Denied",
"errorCode": "AccessDenied",
"message": "Not authorized. Missing capabilities: WRITE:DOCUMENT",
"status": "403 FORBIDDEN",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "Not authorized. Missing capabilities: WRITE:DOCUMENT"
}{
"error": "Entity Not Found",
"errorCode": "EntityNotFound",
"message": "This entity is not found in the system.",
"status": "404 NOT_FOUND",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "This entity is not found in the system."
}{
"error": "Non Unique Entry",
"errorCode": "NonUniqueEntry",
"message": "This entity is required to be unique: lease.pdf",
"status": "409 CONFLICT",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "This entity is required to be unique: lease.pdf"
}CREATE Document via URL
Attaches a Document to a Lease by fetching it from a presigned URL you provide. The URL must use https and its response must carry a Content-Length. Any file type is accepted, up to 200MB. Only documents whose filename ends in .pdf are processed into Pages and Tags; anything else is stored and attached as-is.
Required capabilities: WRITE:DOCUMENT
curl --request POST \
--url https://api.prophia.com/rest/v2/accounts/{accountId}/docs \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"leaseId": "<string>",
"presignedUrl": "<string>",
"filename": "<string>",
"title": "<string>"
}
'import requests
url = "https://api.prophia.com/rest/v2/accounts/{accountId}/docs"
payload = {
"leaseId": "<string>",
"presignedUrl": "<string>",
"filename": "<string>",
"title": "<string>"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
leaseId: '<string>',
presignedUrl: '<string>',
filename: '<string>',
title: '<string>'
})
};
fetch('https://api.prophia.com/rest/v2/accounts/{accountId}/docs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prophia.com/rest/v2/accounts/{accountId}/docs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'leaseId' => '<string>',
'presignedUrl' => '<string>',
'filename' => '<string>',
'title' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.prophia.com/rest/v2/accounts/{accountId}/docs"
payload := strings.NewReader("{\n \"leaseId\": \"<string>\",\n \"presignedUrl\": \"<string>\",\n \"filename\": \"<string>\",\n \"title\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.prophia.com/rest/v2/accounts/{accountId}/docs")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"leaseId\": \"<string>\",\n \"presignedUrl\": \"<string>\",\n \"filename\": \"<string>\",\n \"title\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prophia.com/rest/v2/accounts/{accountId}/docs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"leaseId\": \"<string>\",\n \"presignedUrl\": \"<string>\",\n \"filename\": \"<string>\",\n \"title\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"filename": "<string>",
"title": "<string>",
"numberOfPages": 123,
"docCategory": "Main Lease Agreement",
"createdAt": "2023-11-07T05:31:56Z",
"documentStatus": "<string>",
"splitStatus": "single",
"originalDocId": "<string>"
}{
"error": "Invalid Input",
"errorCode": "InvalidInput",
"message": "dba cannot be blank",
"status": "400 BAD_REQUEST",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "dba cannot be blank"
}{
"error": "JWT authentication is not supported. Use an API key."
}{
"error": "Access Denied",
"errorCode": "AccessDenied",
"message": "Not authorized. Missing capabilities: WRITE:DOCUMENT",
"status": "403 FORBIDDEN",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "Not authorized. Missing capabilities: WRITE:DOCUMENT"
}{
"error": "Entity Not Found",
"errorCode": "EntityNotFound",
"message": "This entity is not found in the system.",
"status": "404 NOT_FOUND",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "This entity is not found in the system."
}{
"error": "Non Unique Entry",
"errorCode": "NonUniqueEntry",
"message": "This entity is required to be unique: lease.pdf",
"status": "409 CONFLICT",
"timestamp": "2026-09-02T20:41:03.118Z",
"localizedMessage": "This entity is required to be unique: lease.pdf"
}Authorizations
Body
Fields for attaching a Document to a Lease via Pre-signed URL.
Lease to attach the Document to. Must belong to the Account in the path and to a Building your api key can access. To upload a file to a Building or Property folder, simply provide the appropriate Building or Property id (UUID) in this field. Note: Does not accept Lease.customId.
1URL Prophia fetches the file from. Must use https, and the response must carry a Content-Length, and the file may be at most 200MB. The URL only needs to be readable for the duration of the request, Prophia will fetch the file during the request and store it in our system.
1Name to store the Document under. This is also what decides whether the file is processed: a name ending in .pdf runs Prophia's ingestion pipeline, anything else is stored and attached as-is with no pages or tags. Filenames must be unique for non-deleted documentsresiding in the same Lease.
1Category to file the Document under. When omitted from this request and the document is processed (a .pdf filename), Prophia's AI will attempt to set the category automatically, with any discrepancies cleaned up during the subsequent onboarding process. Certain categories may be excluded from Reports (usually less critical, non-deal-related categories).
Main Lease Agreement, Extension - Amendment, Expansion - Amendment, Contraction - Amendment, Move - Amendment, Correction - Amendment, New Rights - Amendment, Other - Amendment, Commencement Letter, Work Letter, Lease Abstract, Stacking Plan, Floorplan, Site Plan, Letter of Credit, Letter of Intent, Certificate of Insurance, Notices, Termination Notices, Assignment and Assumption Agreement, Telecom/Antenna Agreement, Storage Agreement, Other, Sublease Agreement, Consent to Sublease, Parking Agreement, Licensing Agreement, Guaranty, Estoppel, Management Office Agreement, Loan Agreement, Letter Agreement, JV Agreement, Closing Document, Purchase & Sale Agreement, Management Agreement, Brokerage Listing Agreement, Real Estate Tax Bills, Capital Projects, Service Agreement, Subordination, Non-Disturbance and Attornment Agreement, Ground Lease, Memorandum of Lease, Rent Roll Response
OK
Representation of a Lease Document. Each Document belongs to one Lease and cannot be duplicated within a single Lease.
Document classification. Certain Document categories may determine which Tags and in-app features the Document is included in. If left blank, Prophia's AI will inspect the Document and set it accordingly, with a human review to follow. The AI will not overwrite an existing category if one is already set.
Main Lease Agreement, Extension - Amendment, Expansion - Amendment, Contraction - Amendment, Move - Amendment, Correction - Amendment, New Rights - Amendment, Other - Amendment, Commencement Letter, Work Letter, Lease Abstract, Stacking Plan, Floorplan, Site Plan, Letter of Credit, Letter of Intent, Certificate of Insurance, Notices, Termination Notices, Assignment and Assumption Agreement, Telecom/Antenna Agreement, Storage Agreement, Other, Sublease Agreement, Consent to Sublease, Parking Agreement, Licensing Agreement, Guaranty, Estoppel, Management Office Agreement, Loan Agreement, Letter Agreement, JV Agreement, Closing Document, Purchase & Sale Agreement, Management Agreement, Brokerage Listing Agreement, Real Estate Tax Bills, Capital Projects, Service Agreement, Subordination, Non-Disturbance and Attornment Agreement, Ground Lease, Memorandum of Lease, Rent Roll Processing state: processing while the document is in Prophia's AI ingestion pipeline, then incomplete followed by any account specific statuses (defined by/through our operations team) and ultimately complete when the Document has been fully processed. To understand how this plays into the broader onboarding state of the Lease and Building see our understanding onboarding conceptual guide.

