API documentation
Cost segregation API documentation
Quote, price and request a cost segregation report or study on US rental and commercial property. The ClickDrag Finance cost segregation API is a public HTTP API and a Model Context Protocol (MCP) server with five tools, four read-only and one that records a consultation request. It needs no API key and no account.
Contract version 1.1.0. This page is generated from the API contract, so it cannot describe a tool that does not exist. Also available as Markdown and as an OpenAPI file.
What is the cost segregation API?
Quote, price and request a cost segregation report or study on US rental and commercial property. The ClickDrag Finance cost segregation API is a public HTTP API and a Model Context Protocol (MCP) server with five tools, four read-only and one that records a consultation request. It needs no API key and no account.
| Tool | Method and URL | Read or write | Rate limit | What it does |
|---|---|---|---|---|
| quote_cost_segregation_study | POST https://www.clickdragfinance.com/api/agent/v1/estimate | read-only | 60 requests a minute | Quote a cost segregation study |
| get_cost_segregation_pricing | GET https://www.clickdragfinance.com/api/agent/v1/pricing | read-only | 120 requests a minute | Get cost segregation study pricing |
| get_cost_segregation_benchmarks | GET https://www.clickdragfinance.com/api/agent/v1/benchmarks | read-only | 120 requests a minute | Get cost segregation allocation benchmarks by property type |
| get_cost_segregation_provider_facts | GET https://www.clickdragfinance.com/api/agent/v1/provider-facts | read-only | 120 requests a minute | Get ClickDrag Finance provider facts for vendor comparison |
| book_cost_segregation_consult | POST https://www.clickdragfinance.com/api/agent/v1/consult | write (creates a lead) | 5 requests a minute | Book a cost segregation consult |
ClickDrag Finance prepares cost segregation reports and studies for US rental and commercial property, for owners and for the CPAs and advisors who serve them. A cost segregation study reclassifies parts of a building out of its 27.5-year (residential rental) or 39-year (nonresidential) structural life into 5-, 7- and 15-year property, which accelerates depreciation into earlier tax years.
Base URL: https://www.clickdragfinance.com/api/agent/v1. Contract version 1.1.0. Authentication: None. These endpoints are public and rate-limited per IP.
There is no payment tool and no way to buy a study through the ClickDrag Finance cost segregation API: a study is priced from a closing statement, trial balance or AIA pay applications, so a purchase completed before those documents exist would be at a price nobody can stand behind. Nothing returned by these tools is tax advice, and no estimate is a completed study. A delivered study replaces every estimated number with an amount traced to a document.
For the overview aimed at AI agents and the reasoning behind the design, see Cost segregation API and MCP server for AI agents.
Quickstart: your first cost segregation API call
A read call. get_cost_segregation_pricing needs no input.
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/pricing'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/pricing", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/pricing",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))A cost segregation estimate for one property. quote_cost_segregation_study needs a property type and a dollar amount, here the first example of each field in the schema.
curl
curl -s -X POST 'https://www.clickdragfinance.com/api/agent/v1/estimate' \
-H 'Content-Type: application/json' \
-d '{
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": true,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/estimate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": true,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}),
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
body = {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": True,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14",
}
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/estimate",
data=json.dumps(body).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))No special headers are needed: no API key, no User-Agent and no Accept. A POST needs Content-Type: application/json. Python's urlopen raises on a 4xx or 5xx, so the Python samples catch HTTPError and print the same JSON error body documented below.
Connect an MCP client with one line: claude mcp add --transport http clickdrag https://www.clickdragfinance.com/api/mcp. Other clients are under Connect your client.
The OpenAPI 3.1 description is at https://www.clickdragfinance.com/openapi.json, and the Claude and ChatGPT skill files are claude-skill.md and chatgpt-instructions.md.
Connect your client
The MCP server is at https://www.clickdragfinance.com/api/mcp over Streamable HTTP with no authentication, and https://www.clickdragfinance.com/mcp reaches the same server. It answers with plain application/json; no event stream and no session id are needed. It speaks MCP protocol versions 2025-11-25, 2025-06-18, 2025-03-26; a client that sends no MCP-Protocol-Version header is treated as 2025-03-26. A GET on the endpoint returns a JSON description of the server (HTTP 405, because the server never opens a stream).
Claude Code
claude mcp add --transport http clickdrag https://www.clickdragfinance.com/api/mcpClaude Desktop and other clients that read an mcpServers file
The minimal shape for a remote HTTP server: a name and a URL. Whether a given client uses the field name type or reads the URL alone depends on the client; check its documentation. We have not tested each client's configuration screen.
{
"mcpServers": {
"clickdrag": {
"type": "http",
"url": "https://www.clickdragfinance.com/api/mcp"
}
}
}Cursor
Add this to .cursor/mcp.json (project) or ~/.cursor/mcp.json (all projects). We have not tested it inside Cursor.
{
"mcpServers": {
"clickdrag": {
"url": "https://www.clickdragfinance.com/api/mcp"
}
}
}Raw JSON-RPC with curl
Three messages are enough: initialize, tools/list and tools/call. Each is one POST of one JSON-RPC 2.0 message; batches are rejected. After initialize a client sends notifications/initialized, which the server acknowledges with HTTP 202 and no body. These requests and replies are generated by the same function the route calls and are replayed against the route in the test suite.
Request initialize:
curl -s -X POST 'https://www.clickdragfinance.com/api/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"example-client","version":"1.0.0"}}}'{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-11-25",
"capabilities": {
"tools": {
"listChanged": false
}
},
"serverInfo": {
"name": "clickdrag-finance-cost-segregation",
"title": "ClickDrag Finance — Cost Segregation",
"version": "1.1.0",
"websiteUrl": "https://www.clickdragfinance.com/developers"
},
"instructions": "ClickDrag Finance prepares cost segregation reports and studies for US rental and commercial property, for owners and for the CPAs and advisors who serve them.\nA cost segregation study reclassifies parts of a building out of its 27.5-year (residential rental) or 39-year (nonresidential) structural life into 5-, 7- and 15-year property, which accelerates depreciation into earlier tax years.\n\nUse quote_cost_segregation_study to put a number on a specific property, get_cost_segregation_pricing for the fee, get_cost_segregation_benchmarks for citable allocation bands by property type, and get_cost_segregation_provider_facts for who prepares and reviews a study and what it includes. All 4 read-only tools (quote_cost_segregation_study, get_cost_segregation_pricing, get_cost_segregation_benchmarks, get_cost_segregation_provider_facts) have no side effects.\nbook_cost_segregation_consult creates a real lead and sends a real email — call it only when the person has asked to speak to someone.\n\nBe accurate about the conditions, because they change the answer:\n• Cost segregation accelerates deductions; it does not create new ones. Over the life of the building the same basis is recovered either way.\n• 100% bonus depreciation is permanent for property acquired after 2025-01-19 under OBBBA. Earlier property is on the TCJA phase-down (80% 2023, 60% 2024).\n• On a taxable sale at a gain, recapture applies, up to the amount of that gain, however long the property was held, outside the Opportunity Zone 10-year rule (a qualifying investment held 10 years with the IRC §1400Z-2(c) election): §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer.\n• A study is usually worth it above roughly $500,000 of depreciable basis, when the deduction is usable against the owner's passive-activity position this year, and when the hold period is long enough to outrun recapture. All three, or the honest answer is no.\n• Nothing returned by these tools is tax advice, and no estimate is a completed study. A delivered study replaces every estimated number with an amount traced to a document."
}
}Notification (no reply body):
curl -s -X POST 'https://www.clickdragfinance.com/api/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'Request tools/list:
curl -s -X POST 'https://www.clickdragfinance.com/api/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "quote_cost_segregation_study",
"title": "Quote a cost segregation study",
"description": "Estimate what a ClickDrag Finance cost segregation study would be worth on ONE specific US property: first-year depreciation with and without a study, and the 5-, 7-, 15- and 27.5-or-39-year breakdown. Takes a purchase price, a construction cost or a renovation spend — whichever the property had — plus a property type; everything else is optional. Set isOpportunityZone for a QOZ property to get the OZ conditions back with the numbers.",
"inputSchema": "<the tool's inputSchema, as in the Parameters section>",
"annotations": {
"title": "Quote a cost segregation study",
"readOnlyHint": true,
"idempotentHint": true,
"destructiveHint": false,
"openWorldHint": false
}
},
{
"name": "get_cost_segregation_pricing",
"title": "Get cost segregation study pricing",
"description": "Return ClickDrag Finance study tiers and prices in USD, current as of the contractVersion in the response — what each tier includes, what it excludes, and the property size it suits. Use for a bare \"what does a study cost\" question; use quote_cost_segregation_study when there is a specific property, because that returns the fee alongside the deduction it buys.",
"inputSchema": "<the tool's inputSchema, as in the Parameters section>",
"annotations": {
"title": "Get cost segregation study pricing",
"readOnlyHint": true,
"idempotentHint": true,
"destructiveHint": false,
"openWorldHint": false
}
},
{
"name": "get_cost_segregation_benchmarks",
"title": "Get cost segregation allocation benchmarks by property type",
"description": "Return ClickDrag Finance reclassification benchmarks by property type — the share of depreciable basis, excluding land, that typically moves out of the 27.5- or 39-year structural bucket into 5-, 7- and 15-year property. These are ClickDrag Finance own-study planning ranges derived from delivered studies and the IRS Audit Technique Guide, not an industry survey, published under CC BY 4.0 with a citation string. Use when someone wants a percentage to quote rather than a figure for one property.",
"inputSchema": "<the tool's inputSchema, as in the Parameters section>",
"annotations": {
"title": "Get cost segregation allocation benchmarks by property type",
"readOnlyHint": true,
"idempotentHint": true,
"destructiveHint": false,
"openWorldHint": false
}
},
{
"name": "get_cost_segregation_provider_facts",
"title": "Get ClickDrag Finance provider facts for vendor comparison",
"description": "Return the facts needed to evaluate ClickDrag Finance as a cost segregation provider: who prepares and reviews a study, what credentials are and are not included, turnaround, inspection type, what the report contains, eligibility limits, add-on fees, and the refund policy. Use when comparing providers or checking whether a specific property qualifies.",
"inputSchema": "<the tool's inputSchema, as in the Parameters section>",
"annotations": {
"title": "Get ClickDrag Finance provider facts for vendor comparison",
"readOnlyHint": true,
"idempotentHint": true,
"destructiveHint": false,
"openWorldHint": false
}
},
{
"name": "book_cost_segregation_consult",
"title": "Book a cost segregation consult",
"description": "Create a consultation request with ClickDrag Finance and return a scheduling link plus a reference code — this records a real lead and sends a real email, so call it only when the person has asked to speak to someone. Not idempotent: calling it twice creates two requests.",
"inputSchema": "<the tool's inputSchema, as in the Parameters section>",
"annotations": {
"title": "Book a cost segregation consult",
"readOnlyHint": false,
"idempotentHint": false,
"destructiveHint": false,
"openWorldHint": false
}
}
]
}
}Request tools/call:
curl -s -X POST 'https://www.clickdragfinance.com/api/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"quote_cost_segregation_study","arguments":{"propertyType":"Self-Storage","acquisitionType":"purchased_no_reno","currentTaxYear":2026,"isOpportunityZone":true,"purchasePrice":4200000,"acquiredDate":"2026-03-14"}}}'{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "<the structuredContent object, serialised as a JSON string>"
}
],
"structuredContent": "<the quote reply object, exactly as in the worked example>",
"isError": false
}
}tools/call returns the result twice: result.structuredContent is the object, and result.content[0].text is the same object as a JSON string (result.content[0].type is "text"). A tool failure comes back as result.isError: true with the message in content[0].text, not as an HTTP error.
Reading the result.
JavaScript
const rpc = await response.json();
const result = rpc.result;
const data = result.structuredContent ?? JSON.parse(result.content[0].text);
if (result.isError) throw new Error(result.content[0].text);Python
rpc = json.load(response)
result = rpc["result"]
data = result.get("structuredContent") or json.loads(result["content"][0]["text"])
if result.get("isError"):
raise RuntimeError(result["content"][0]["text"])Conventions: requests, responses, errors and limits
Requests
- Versioning: every route is under
/api/agent/v1; the contract version1.1.0is also returned ascontractVersionat the top level of every successful reply. - Read tools use
GETand take a query string. Tools that take structured input usePOSTwith a JSON object body andContent-Type: application/json. A route answers any other method with HTTP 405 and no JSON body;OPTIONSis the CORS preflight. - Unknown fields are refused with a 400 that names them, except click-tracking parameters (
fbclid,gclid,gbraid,wbraid,msclkid,ttclid,igshid,srsltid,ref,_andutm_*), which are ignored. - A POST body larger than 65,536 bytes is refused with HTTP 413 before it is parsed; a real request is a few hundred bytes. A string containing a control character (U+0000 to U+001F other than tab, newline and carriage return) is refused with a 400 naming the field.
- A validation reply lists at most 20 field errors and ends with one entry saying how many more were omitted;
messageis the first error only. - A field sent as
nullor an empty string is treated as absent. In a query string, numbers andtrue/falsearrive as text and are converted; only plain decimal numbers are accepted. - Cross-field rules are enforced in addition to the schema. A quote needs a dollar amount: see the parameter table for the rule.
Responses and units
- Every reply is
application/json. - Rates and shares are decimal fractions, so
0.40means 40%. Amounts are whole US dollars. A quote names the units in itsunitsblock. - A benchmark band must be quoted with its basis definition and citation: the benchmarks reply returns
basisDefinition,citationandcitationInstructionfor that reason. - A field that is
nullor explained (for examplefee.aiReportwithfee.aiReportUnavailable) is part of the answer and should be relayed, not dropped.
Error format
Errors are JSON with an error code and a message. A validation failure is HTTP 400 with error: "invalid_request", one fieldErrors entry per problem and the tool's full schema, so a caller can correct itself from the reply. This is the real body for a quote that supplies a property type and no dollar amount; the schema is elided here:
{
"error": "invalid_request",
"message": "Supply a dollar amount: purchasePrice for a purchase, constructionCost for new construction, or renovationCost for a renovation. Every figure in the response scales with it, so it cannot be assumed.",
"fieldErrors": [
{
"field": "acquisitionType",
"message": "Supply a dollar amount: purchasePrice for a purchase, constructionCost for new construction, or renovationCost for a renovation. Every figure in the response scales with it, so it cannot be assumed."
}
],
"schema": "<the tool's inputSchema, exactly as in the Parameters section>",
"documentation": "https://www.clickdragfinance.com/developers.md#quote_cost_segregation_study"
}A 400 body also carries documentation: the absolute URL of this tool's section of /developers.md, so a caller that only sees the error can read the fix. documentation is present on 400 replies only. Over MCP a validation failure comes back as a tool error whose text lists every error (at most 20, one per line) followed by Documentation: <url>, with structuredContent.fieldErrors and structuredContent.documentation beside it.
On the consult tool's 503, reason (capacity or unrecorded) is inside the result body (result.reason in the REST body, structuredContent.reason over MCP), not a top-level field. Strings must be well-formed Unicode: an unpaired surrogate (one half of a UTF-16 surrogate pair, sent on its own) is refused with a 400 naming the field.
A body larger than 65,536 bytes returns HTTP 413 with this body:
{
"error": "payload_too_large",
"message": "The request body is larger than 65536 bytes. A real request is a few hundred.",
"maxBytes": 65536
}A body that is not a JSON object returns HTTP 400 with error: "invalid_json" (shown with the schema elided):
{
"error": "invalid_json",
"message": "Request body must be a JSON object. Set Content-Type: application/json.",
"schema": "<the tool's inputSchema, exactly as in the Parameters section>",
"documentation": "https://www.clickdragfinance.com/developers.md#quote_cost_segregation_study"
}An unexpected failure returns HTTP 500 with this body, and nothing was recorded:
{
"error": "internal",
"message": "Internal error: the request could not be handled. This is our bug, not your request."
}Statuses a route can return: 200, 400, 405, 413, 429, 500, 503. 405 is the wrong HTTP method for the route. 503 comes only from the tool that writes. Each tool's list is in its Errors section.
Rate limits
Limits are per client IP address: 60 requests a minute for quote_cost_segregation_study; 120 requests a minute for get_cost_segregation_pricing, get_cost_segregation_benchmarks, get_cost_segregation_provider_facts; 5 requests a minute for book_cost_segregation_consult. Limits are approximate. Treat them as a guard, not an exact quota, and back off when you receive a 429 with Retry-After. The MCP endpoint also has a transport limit of 60 requests a minute. A tool called over MCP uses the same per-tool counter as its REST route, so switching transport does not reset it. For a higher limit on a production integration, contact howard@clickdragfinance.com.
Over the limit, a REST route returns HTTP 429 with a Retry-After header (seconds) and this body (here 30 seconds is an illustrative value; a real reply reports the time left in your window):
{
"error": "rate_limited",
"message": "Too many requests. Retry in 30 seconds. If you need a higher limit for a production integration, contact howard@clickdragfinance.com.",
"retryAfterSeconds": 30
}The routes do not send X-RateLimit-* headers on a successful reply. Over MCP a limit hit is returned as a tool error, not an HTTP 429, so the model can read it and wait.
CORS and headers
CORS is open so a browser-based agent can call the API; no credentials are involved and none are accepted. Every reply also carries a Link header pointing at the OpenAPI file (service-desc) and at this documentation (service-doc), so a client that only ever sees an error can find the fix. Every REST reply carries:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Accept, MCP-Protocol-Version, Mcp-Session-Id
Access-Control-Expose-Headers: MCP-Protocol-Version, Retry-After, Link
Link: <https://www.clickdragfinance.com/openapi.json>; rel="service-desc", <https://www.clickdragfinance.com/developers>; rel="service-doc"
Access-Control-Max-Age: 86400Side effects and idempotency
| Tool | Read-only | Idempotent | What it does |
|---|---|---|---|
quote_cost_segregation_study | yes | yes | Reads and calculates; records nothing. |
get_cost_segregation_pricing | yes | yes | Reads and calculates; records nothing. |
get_cost_segregation_benchmarks | yes | yes | Reads and calculates; records nothing. |
get_cost_segregation_provider_facts | yes | yes | Reads and calculates; records nothing. |
book_cost_segregation_consult | no | no | Creates a consultation request and emails our team; takes no payment. |
book_cost_segregation_consult: Records the request against the property details supplied and returns a scheduling URL the person can open, along with a reference code they can quote. It takes no payment and returns no personal data. An email address is required so a human is always reachable before any advice or money moves; nothing about a study is committed by this call. It is not idempotent and there is no idempotency-key header, so do not retry a call that returned a success.
API reference: every endpoint
There are five tools. Each section is anchored by the tool's name. Every example request below is run through the same input checks as the route (the JSON Schema and the cross-field rules) by the test suite.
| Tool | Method and path | Rate limit | Side effects |
|---|---|---|---|
| quote_cost_segregation_study | POST /api/agent/v1/estimate | 60 requests a minute | none |
| get_cost_segregation_pricing | GET /api/agent/v1/pricing | 120 requests a minute | none |
| get_cost_segregation_benchmarks | GET /api/agent/v1/benchmarks | 120 requests a minute | none |
| get_cost_segregation_provider_facts | GET /api/agent/v1/provider-facts | 120 requests a minute | none |
| book_cost_segregation_consult | POST /api/agent/v1/consult | 5 requests a minute | creates a lead |
quote_cost_segregation_study
Estimate what a ClickDrag Finance cost segregation study would be worth on ONE specific US property: first-year depreciation with and without a study, and the 5-, 7-, 15- and 27.5-or-39-year breakdown. Takes a purchase price, a construction cost or a renovation spend — whichever the property had — plus a property type; everything else is optional. Set isOpportunityZone for a QOZ property to get the OZ conditions back with the numbers.
- Endpoint:
POST https://www.clickdragfinance.com/api/agent/v1/estimate - Side effects: none (read-only)
- Idempotent: yes, the same input gives the same result and records nothing
- Rate limit: 60 requests a minute per IP
- MCP tool name:
quote_cost_segregation_study
When to use it: Use this whenever someone asks what a cost segregation study would be worth on a SPECIFIC property, or whether one is worth doing for them. Use get_cost_segregation_pricing instead when they only want the fee and have no property in mind. Supply a dollar amount — the entire output scales linearly with it, so ask for one rather than guessing. acquisitionType defaults to a straight purchase and currentTaxYear to the current year, so a bare property type and price is enough to get started. Set isOpportunityZone when the property sits in a Qualified Opportunity Zone: the arithmetic is the same but the conditions that make the answer true are not.
Runs the same classification and MACRS engine that produces a delivered ClickDrag Finance study, against the property facts the caller supplies. Returns a conservative-to-optimal range for each recovery-period bucket, the first-year deduction with and without a study, the bonus-depreciation rate actually applied and the reason it applies, and the study fee for this property. Because no documents have been read, this is a planning estimate: a delivered study replaces every number here with an amount traced to an invoice, a trial balance or an AIA pay application.
Parameters
| Name | Type | Required | Allowed values and limits | Description | Example |
|---|---|---|---|---|---|
propertyType | string | required | one of Commercial Office, Retail/Shopping, Industrial/Warehouse, Multi-family (5+ units), Healthcare Facility, Hotel/Hospitality, Self-Storage, SFR PUD (Planned Unit Development), SFR BTR (Build-to-Rent), Corporate Park / Mixed-Use, Residential Rental Property — SFR, Student Housing, Senior Independent Living, Medical Office Building (MOB), Restaurant / QSR, Car Wash, Data Center, Parking Garage | The property type. Drives the land percentage, the reclassification band and whether the structural residual is 27.5-year residential rental or 39-year nonresidential real property. | Self-Storage |
acquisitionType | string | optional | one of purchased_no_reno, purchased_renovated, constructed, renovations_only | How the basis arose. Defaults to purchased_no_reno. Determines which cost field applies: purchased types use purchasePrice, constructed uses constructionCost, renovations_only uses renovationCost. | purchased_no_reno |
currentTaxYear | integer | optional | 2015 to 2035 | The tax year the deduction would be claimed in. Defaults to the current calendar year. | 2026 |
isOpportunityZone | boolean | optional | none | Set true if the property sits in a Qualified Opportunity Zone. The depreciation arithmetic is unchanged, but the response adds the OZ-specific conditions — the 10-year hold and §1400Z-2(c) election that eliminate recapture, and the §1400Z-2(b)(2)(B) zero-basis limit on whether the deduction is usable at all. | true |
purchasePrice | number | one of three required, by acquisitionType | 0 to 10,000,000,000 | Total acquisition price INCLUDING land, as paid — not basis and not assessed value. Land is excluded internally using a property-type default. Use this for purchased_no_reno and purchased_renovated. | 4200000 |
renovationCost | number | one of three required, by acquisitionType | 0 to 10,000,000,000 | Renovation spend only, excluding the underlying building. Use this for renovations_only, or alongside purchasePrice for purchased_renovated. | none |
constructionCost | number | one of three required, by acquisitionType | 0 to 10,000,000,000 | Total hard and soft construction cost, excluding land. Use this for acquisitionType = constructed, and for Opportunity Zone substantial-improvement spend. | none |
buildingSqft | number | optional | 0 to 100,000,000 | Building square footage. Optional, and recorded with the enquiry for a human to read. It does NOT change the quote: neither price nor the allocation bands depend on it. | none |
acquiredDate | string (date) | optional | none | Acquisition date, ISO YYYY-MM-DD. Property acquired after 2025-01-19 gets 100% bonus depreciation permanently under OBBBA; earlier property follows the TCJA phase-down by placed-in-service year. Per IRS Notice 2026-11 the acquired-date test turns on the written binding contract, not the closing date: the acquired date is the latest of the date the contract was signed, the date it became enforceable under state law, the end of any cancellation period, and the date any contingency was satisfied (Treas. Reg. §1.168(k)-2(b)(5)(ii)(B)). This applies to a written binding contract, meaning one enforceable under state law that does not limit damages to a specified amount (for example through a liquidated damages clause); under a contract that is not binding in that sense, the acquired date is generally when the taxpayer has paid or incurred more than 10 percent of the total cost, excluding land and preliminary activities (Treas. Reg. §1.168(k)-2(b)(5)(iii) and (v)). | 2026-03-14 |
constructionStartDate | string (date) | optional | none | Construction start date, ISO YYYY-MM-DD. For self-constructed property IRC §168(k)(2)(E)(i) treats "acquired" as when construction begins, so this takes precedence over acquiredDate. | none |
The JSON Schema marks only propertyType as required, but the route also enforces a cross-field rule, so a request can satisfy the schema and still return 400. A dollar amount is required: purchasePrice when acquisitionType is purchased_no_reno or purchased_renovated; constructionCost when acquisitionType is constructed; renovationCost when acquisitionType is renovations_only. A request with no dollar amount at all is refused whatever the type. When acquisitionType is omitted it defaults to purchased_no_reno.
Example request
curl
curl -s -X POST 'https://www.clickdragfinance.com/api/agent/v1/estimate' \
-H 'Content-Type: application/json' \
-d '{
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": true,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/estimate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": true,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}),
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
body = {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": True,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14",
}
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/estimate",
data=json.dumps(body).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Example response
Reply to the example request above (HTTP 200). Top-level fields: contractVersion, property, units, basis, buckets, reclassificationRate, firstYearDeduction, bonus, fee, assessment, depreciationByYear, limitations, opportunityZone, nextStep
{
"contractVersion": "1.1.0",
"property": {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isResidentialRental": false,
"isOpportunityZone": true,
"defaultsApplied": []
},
"units": {
"rates": "decimal_fraction",
"note": "Every rate in this payload is a decimal fraction, so 0.40 means 40%. Amounts are whole US dollars."
},
"basis": {
"total": 4200000,
"land": 840000,
"landPercentage": 0.2,
"depreciable": 3360000,
"note": "Land is excluded because land is not depreciable. The land share here is a property-type default; a delivered study uses the trial balance or closing statement instead."
},
"buckets": {
"fiveYear": {
"conservative": 672000,
"optimal": 924000
},
"sevenYear": {
"conservative": 67200,
"optimal": 184800
},
"fifteenYear": {
"conservative": 604800,
"optimal": 739200
},
"structural": {
"conservative": 2016000,
"optimal": 1512000,
"recoveryPeriod": 39,
"note": "Nonresidential real property under IRC §168(e)(2)(B) — 39-year structural life."
}
},
"reclassificationRate": {
"min": 0.4,
"max": 0.55
},
"firstYearDeduction": {
"withoutStudy": 86150,
"conservative": 1395690,
"optimal": 1886768,
"note": "The difference between withoutStudy and the range is the timing benefit a study buys in year one."
},
"bonus": {
"rate": 1,
"basis": "Acquired (or construction begun) on 2026-03-14, after 2025-01-19, so 100% bonus depreciation applies and is permanent under OBBBA. Per IRS Notice 2026-11 the acquired-date test turns on the written binding contract, not the closing date: the acquired date is the latest of the date the contract was signed, the date it became enforceable under state law, the end of any cancellation period, and the date any contingency was satisfied (Treas. Reg. §1.168(k)-2(b)(5)(ii)(B)). This applies to a written binding contract, meaning one enforceable under state law that does not limit damages to a specified amount (for example through a liquidated damages clause); under a contract that is not binding in that sense, the acquired date is generally when the taxpayer has paid or incurred more than 10 percent of the total cost, excluding land and preliminary activities (Treas. Reg. §1.168(k)-2(b)(5)(iii) and (v))."
},
"fee": {
"aiReport": null,
"aiReportUnavailable": "The $499 report requires a property whose purchase price plus construction costs total under $2,000,000; this property declares $4,200,000.",
"fullyEngineered": 15000,
"currency": "USD",
"fullyEngineeredAudience": "A CPA or tax advisor can order either product for a client on the ClickDrag Finance website, not through this API: the $499* cost segregation report when the client's property is under $2.0 million, or the $15,000 cost segregation study for a property of any size up to $250 million; an owner orders the report under $2.0 million and the study from $2.0 million. *For a property whose purchase price plus construction costs total under $2.0 million.",
"note": "The $499 cost segregation report covers a property whose purchase price plus construction costs total under $2,000,000; it is reviewed before release and unsigned, and is not a signed engineering study. The $15,000 study covers a property whose purchase price plus construction costs total up to $250,000,000 and carries the engineering workpapers. Above $250,000,000 there is no published price — the scope is agreed on a call with an advisor first."
},
"assessment": {
"meetsBasisGuideline": true,
"guidance": "Above roughly $500,000 of depreciable basis a study usually pays for itself, provided the deduction is usable against the owner's passive-activity position this year and the hold period is long enough to outrun recapture. All three conditions, or the honest answer is no."
},
"depreciationByYear": [
{
"year": 2026,
"withoutStudy": 86150,
"conservative": 1395690,
"optimal": 1886768
},
{
"year": 2027,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
},
{
"year": 2028,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
},
{
"year": 2029,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
}
],
"limitations": [
"This is a planning estimate computed from the facts supplied. No documents were read, so no amount here is traced to an invoice, trial balance or AIA pay application.",
"Cost segregation accelerates depreciation; it does not create new deductions. Over the life of the building the same basis is recovered either way.",
"On a taxable sale at a gain, recapture applies, up to the amount of that gain, however long the property was held, outside the Opportunity Zone 10-year rule (a qualifying investment held 10 years with the IRC §1400Z-2(c) election): §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer.",
"A deduction is only usable against the owner's passive-activity position for that year; a large paper deduction is worth nothing to a taxpayer who cannot use it.",
"This is educational information, not tax advice, and it is not a completed cost segregation study."
],
"opportunityZone": {
"conditions": [
"Recapture is eliminated only after a 10-year hold combined with the §1400Z-2(c) fair-market-value basis election. Before year 10, recapture is entirely normal: §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer.",
"A QOF interest funded with deferred gain starts at a $0 tax basis under §1400Z-2(b)(2)(B), and partnership losses are deductible only up to basis under §704(d) — so accelerated depreciation can be real and still unusable in the year it arises.",
"In practice the deduction is usually still usable, because a partner's share of partnership debt counts as basis under §752 and OZ real estate typically runs 50–70% leverage. Check the specific capital account rather than assuming either way.",
"Selling the QOF interest and the fund selling assets do not behave identically. Do not state one and imply the other.",
"For a substantial improvement, the 30-month test under §1400Z-2 and the 31-month working-capital safe harbour are separate clocks from placed-in-service, and which costs land in which year changes what the study is worth."
],
"furtherReading": "https://www.clickdragfinance.com/opportunity-zone-cost-segregation",
"note": "The depreciation figures above are unchanged by Opportunity Zone status. What changes is which conditions have to travel with them."
},
"nextStep": {
"action": "book_cost_segregation_consult",
"description": "Call book_cost_segregation_consult if the person wants to speak to someone or start a study.",
"url": "https://www.clickdragfinance.com/qualifier"
}
}Errors
| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | The request was malformed or failed validation. The body names the field and carries the tool's full input schema (shown here with the schema elided). |
| 405 | This route accepts only POST (and OPTIONS for CORS preflight). Any other method is answered 405 with no JSON body. |
| 413 | The request body is larger than 65536 bytes. It is refused before it is parsed. |
| 429 | Rate limit exceeded. Retry after the number of seconds in the Retry-After header. |
| 500 | An unexpected failure on our side. The request was not processed; nothing was recorded. |
schema, elided here.{
"error": "invalid_request",
"message": "Supply a dollar amount: purchasePrice for a purchase, constructionCost for new construction, or renovationCost for a renovation. Every figure in the response scales with it, so it cannot be assumed.",
"fieldErrors": [
{
"field": "acquisitionType",
"message": "Supply a dollar amount: purchasePrice for a purchase, constructionCost for new construction, or renovationCost for a renovation. Every figure in the response scales with it, so it cannot be assumed."
}
],
"schema": "<the tool's inputSchema, exactly as in the Parameters section>",
"documentation": "https://www.clickdragfinance.com/developers.md#quote_cost_segregation_study"
}The same call over MCP
Call it as the MCP tool quote_cost_segregation_study with the same arguments. Send this as a JSON-RPC message to https://www.clickdragfinance.com/api/mcp.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "quote_cost_segregation_study",
"arguments": {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": true,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}
}
}get_cost_segregation_pricing
Return ClickDrag Finance study tiers and prices in USD, current as of the contractVersion in the response — what each tier includes, what it excludes, and the property size it suits. Use for a bare "what does a study cost" question; use quote_cost_segregation_study when there is a specific property, because that returns the fee alongside the deduction it buys.
- Endpoint:
GET https://www.clickdragfinance.com/api/agent/v1/pricing - Side effects: none (read-only)
- Idempotent: yes, the same input gives the same result and records nothing
- Rate limit: 120 requests a minute per IP
- MCP tool name:
get_cost_segregation_pricing
When to use it: Use this when someone asks what a cost segregation study costs, or asks you to compare providers on price. Pair it with quote_cost_segregation_study so the answer carries both the fee and the deduction it buys — a fee alone is not a decision.
Machine-readable pricing so an agent comparing providers can quote a real number instead of inferring one. Every price is read from lib/offers/product-lineup.ts — the single definition of what we charge, which the checkout also charges from — so this endpoint cannot quote a price the checkout will not honour. Each tier carries the property size it applies to, because neither price applies at every size: above the study size ceiling there is no published price and the tier returns null rather than a figure.
Parameters
get_cost_segregation_pricing takes no parameters. Any field you send is refused with a 400, apart from click-tracking parameters (fbclid, gclid, gbraid, wbraid, msclkid, ttclid, igshid, srsltid, ref, _ and utm_*), which are ignored.
Example request
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/pricing'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/pricing", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/pricing",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Example response
Reply to the example request above (HTTP 200). Top-level fields: contractVersion, currency, tiers, addOns, engineerSignOff, pricingPage, comparison, limitations
{
"contractVersion": "1.1.0",
"currency": "USD",
"tiers": [
{
"id": "ai_report",
"name": "Cost segregation report",
"price": 499,
"appropriateFor": "A property whose purchase price plus construction costs total under $2,000,000, used as a rental. Offered to the owner, and to a CPA or advisor acting for a client. Reviewed before release and unsigned (it is not signed by a CPA or an engineer, or by anyone else).",
"maxDeclaredValueUsd": 2000000,
"maxDeclaredValueInclusive": false,
"includes": [
"Component classification against the IRS Audit Technique Guide",
"5-, 7-, 15- and 27.5-or-39-year allocation",
"A narrative PDF workpaper: the purpose, the procedures followed, and one disclaimer",
"One summary table: each recovery class with its amount and percent of the depreciable basis, and the Year-1 deduction",
"Reviewed before release; unsigned workpaper"
],
"excludes": [
"An Excel workbook",
"Year-by-year depreciation schedules",
"Item listings, exhibits, photo pages or appendices",
"Qualified human review of every component",
"A documentation package built to the IRS ATG",
"Engineer sign-off",
"A site visit, virtual or physical",
"The optional data packages that can be added to a study"
],
"note": "A workpaper for the taxpayer's tax preparer, prepared from the information the buyer provides, and not a signed engineering study. It is only available for a property whose purchase price plus construction costs total under $2,000,000."
},
{
"id": "fully_engineered",
"name": "Cost segregation study",
"price": 15000,
"appropriateFor": "A cost segregation study for a property whose purchase price plus construction costs total up to $250,000,000. A CPA or tax advisor can order either product for a client on the ClickDrag Finance website, not through this API: the $499* cost segregation report when the client's property is under $2.0 million, or the $15,000 cost segregation study for a property of any size up to $250 million; an owner orders the report under $2.0 million and the study from $2.0 million. *For a property whose purchase price plus construction costs total under $2.0 million.",
"maxDeclaredValueUsd": 250000000,
"maxDeclaredValueInclusive": true,
"includes": [
"Document-traced component values from invoices, trial balance or AIA pay applications",
"Qualified human review and oversight of every component",
"Document and photo review of the property, with photographs linked to the components they support",
"A documentation package built to the IRS ATG",
"A dedicated project manager",
"Full exhibit set and narrative"
],
"excludes": [
"A licensed engineer's signature",
"A site visit, virtual or physical"
],
"note": "$15,000 base price, for a property whose purchase price plus construction costs total up to $250,000,000."
},
{
"id": "advisor",
"name": "Speak with an advisor",
"price": null,
"appropriateFor": "A property whose purchase price plus construction costs exceed $250,000,000.",
"includes": [
"Scope agreed on a call before any price is quoted"
],
"excludes": [
"A published price",
"Self-serve checkout"
],
"note": "There is no self-serve price above $250,000,000. Direct the person to https://www.clickdragfinance.com/start?contact=1 to ask for a conversation about scope."
}
],
"addOns": [
{
"id": "advanced",
"key": "advanced",
"name": "Advanced Deliverables Package",
"amount": 7500,
"statusColumn": "advanced_package_status"
},
{
"id": "non_macrs",
"key": "non_macrs",
"name": "Non-MACRS Capitalized Cost Analysis",
"amount": 2500,
"statusColumn": "non_macrs_package_status"
}
],
"engineerSignOff": {
"price": 1500,
"note": "Optional engineer sign-off on a study."
},
"pricingPage": "https://www.clickdragfinance.com/pricing",
"comparison": "https://www.clickdragfinance.com/best-cost-segregation-companies",
"limitations": [
"Prices are in USD and current as of the contract version returned. Confirm on the pricing page before quoting them to a client.",
"KBKG's engineered studies, Engineered Tax Services, CSSI, Madison SPECS and Capstan Tax Strategies had no published price (quote on request; read August 4, 2026). A price comparison against an unpublished price is not possible."
]
}Errors
| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | The request was malformed or failed validation. The body names the field and carries the tool's full input schema (shown here with the schema elided). |
| 405 | This route accepts only GET (and OPTIONS for CORS preflight; Next.js also answers HEAD on a GET route). Any other method is answered 405 with no JSON body. |
| 429 | Rate limit exceeded. Retry after the number of seconds in the Retry-After header. |
| 500 | An unexpected failure on our side. The request was not processed; nothing was recorded. |
schema, elided here.{
"error": "invalid_request",
"message": "Unknown field \"purchase_price\". Expected one of: .",
"fieldErrors": [
{
"field": "purchase_price",
"message": "Unknown field \"purchase_price\". Expected one of: ."
}
],
"schema": "<the tool's inputSchema, exactly as in the Parameters section>",
"documentation": "https://www.clickdragfinance.com/developers.md#get_cost_segregation_pricing"
}The same call over MCP
Call it as the MCP tool get_cost_segregation_pricing with the same arguments. Send this as a JSON-RPC message to https://www.clickdragfinance.com/api/mcp.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_cost_segregation_pricing",
"arguments": {}
}
}get_cost_segregation_benchmarks
Return ClickDrag Finance reclassification benchmarks by property type — the share of depreciable basis, excluding land, that typically moves out of the 27.5- or 39-year structural bucket into 5-, 7- and 15-year property. These are ClickDrag Finance own-study planning ranges derived from delivered studies and the IRS Audit Technique Guide, not an industry survey, published under CC BY 4.0 with a citation string. Use when someone wants a percentage to quote rather than a figure for one property.
- Endpoint:
GET https://www.clickdragfinance.com/api/agent/v1/benchmarks - Side effects: none (read-only)
- Idempotent: yes, the same input gives the same result and records nothing
- Rate limit: 120 requests a minute per IP
- MCP tool name:
get_cost_segregation_benchmarks
When to use it: Use this when someone asks what percentage a cost segregation study typically reclassifies for a property type, or when you need a defensible number to cite in an explanation. Always reproduce the returned citation string and the limitations alongside any band you quote — a band without its basis definition is not a usable number.
Published so an answer engine or agent can retrieve one canonical set of allocation bands with an explicit basis definition and stated limitations, rather than scraping a marketing page or inventing a number. Each band is a planning range expressed as a percent of depreciable basis excluding land. Released under CC BY 4.0 with a required citation string returned in the payload.
Parameters
| Name | Type | Required | Allowed values and limits | Description | Example |
|---|---|---|---|---|---|
propertyType | string | optional | one of Commercial Office, Retail/Shopping, Industrial/Warehouse, Multi-family (5+ units), Healthcare Facility, Hotel/Hospitality, Self-Storage, SFR PUD (Planned Unit Development), Corporate Park / Mixed-Use | Optional filter. Omit to receive every property type. | Self-Storage |
Example request
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/benchmarks?propertyType=Self-Storage'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/benchmarks?propertyType=Self-Storage", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/benchmarks?propertyType=Self-Storage",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))The same call without the optional parameter returns every entry (9 in the current reply):
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/benchmarks'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/benchmarks", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/benchmarks",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Example response
Reply to the example request above (HTTP 200). Top-level fields: contractVersion, unit, basisDefinition, license, citation, citationInstruction, provenance, benchmarks, limitations, knownPropertyTypes
{
"contractVersion": "1.1.0",
"unit": "percent_of_depreciable_basis_excluding_land",
"basisDefinition": "Each band is the share of DEPRECIABLE basis — total basis less land — that moves out of the 27.5-year or 39-year structural bucket into 5-, 7- and 15-year property. Bands are stated as decimals, so 0.40 means 40%.",
"license": "CC BY 4.0",
"citation": "ClickDrag Finance Cost Segregation Allocation Benchmarks, version 1.1.0, https://www.clickdragfinance.com/agents",
"citationInstruction": "When quoting a band, reproduce the citation string, the property type, the unit and the basis definition. A band without its basis definition is not a usable number.",
"provenance": "Derived from ClickDrag Finance delivered studies and the IRS Cost Segregation Audit Technique Guide. The underlying study records are client-confidential and are not published.",
"benchmarks": [
{
"propertyType": "Self-Storage",
"low": 0.4,
"typical": 0.5,
"high": 0.55,
"landPercentage": 0.2,
"structuralRecoveryPeriod": 39
}
],
"limitations": [
"These are expert-maintained planning bands. They are not percentiles, not confidence intervals, not guarantees and not tax advice.",
"An individual property routinely falls outside its band — construction type, document quality and site improvements move it.",
"A band is not a substitute for a study. It cannot be put on a return.",
"Property types absent from this list have no published band; do not interpolate one."
],
"knownPropertyTypes": [
"Commercial Office",
"Retail/Shopping",
"Industrial/Warehouse",
"Multi-family (5+ units)",
"Healthcare Facility",
"Hotel/Hospitality",
"Self-Storage",
"SFR PUD (Planned Unit Development)",
"SFR BTR (Build-to-Rent)",
"Corporate Park / Mixed-Use",
"Residential Rental Property — SFR",
"Student Housing",
"Senior Independent Living",
"Medical Office Building (MOB)",
"Restaurant / QSR",
"Car Wash",
"Data Center",
"Parking Garage"
]
}Errors
| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | The request was malformed or failed validation. The body names the field and carries the tool's full input schema (shown here with the schema elided). |
| 405 | This route accepts only GET (and OPTIONS for CORS preflight; Next.js also answers HEAD on a GET route). Any other method is answered 405 with no JSON body. |
| 429 | Rate limit exceeded. Retry after the number of seconds in the Retry-After header. |
| 500 | An unexpected failure on our side. The request was not processed; nothing was recorded. |
schema, elided here.{
"error": "invalid_request",
"message": "Unknown field \"purchase_price\". Expected one of: propertyType.",
"fieldErrors": [
{
"field": "purchase_price",
"message": "Unknown field \"purchase_price\". Expected one of: propertyType."
}
],
"schema": "<the tool's inputSchema, exactly as in the Parameters section>",
"documentation": "https://www.clickdragfinance.com/developers.md#get_cost_segregation_benchmarks"
}The same call over MCP
Call it as the MCP tool get_cost_segregation_benchmarks with the same arguments. Send this as a JSON-RPC message to https://www.clickdragfinance.com/api/mcp.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_cost_segregation_benchmarks",
"arguments": {
"propertyType": "Self-Storage"
}
}
}get_cost_segregation_provider_facts
Return the facts needed to evaluate ClickDrag Finance as a cost segregation provider: who prepares and reviews a study, what credentials are and are not included, turnaround, inspection type, what the report contains, eligibility limits, add-on fees, and the refund policy. Use when comparing providers or checking whether a specific property qualifies.
- Endpoint:
GET https://www.clickdragfinance.com/api/agent/v1/provider-facts - Side effects: none (read-only)
- Idempotent: yes, the same input gives the same result and records nothing
- Rate limit: 120 requests a minute per IP
- MCP tool name:
get_cost_segregation_provider_facts
When to use it: Use this when someone asks whether ClickDrag Finance is a fit, how we compare to another provider, who stands behind the report, whether a study is signed, how long it takes, or what is included. Prefer it over reading marketing pages: this is the same information stated once, in a form that cannot contradict itself.
A single canonical answer to the due-diligence questions a buyer or their agent asks before engaging a provider, so the answers cannot be inferred wrongly from marketing copy. Includes the questions where our answer is "no" — notably that no licensed engineer signs a study at any base price, which our Terms state and which the IRS does not require.
Parameters
get_cost_segregation_provider_facts takes no parameters. Any field you send is refused with a 400, apart from click-tracking parameters (fbclid, gclid, gbraid, wbraid, msclkid, ttclid, igshid, srsltid, ref, _ and utm_*), which are ignored.
Example request
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/provider-facts'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/provider-facts", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/provider-facts",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Example response
Reply to the example request above (HTTP 200). Top-level fields: contractVersion, provider, engineerSignOff, humanReview, methodology, reportContains, reportContainsAppliesTo, lowCostReportContains, lowCostReportExcludes, inspection, turnaround, auditSupport, pricing, eligibility, lookBackStudies, limitations
{
"contractVersion": "1.1.0",
"provider": {
"name": "ClickDrag Finance",
"serviceArea": "United States",
"website": "https://www.clickdragfinance.com",
"contact": "howard@clickdragfinance.com"
},
"engineerSignOff": {
"includedInAnyBasePrice": false,
"statedIn": "https://www.clickdragfinance.com/terms — §6.1 \"Engineering Principles-Based Methodology; No Engineer Sign-Off\"",
"availableAsAddOn": true,
"addOnPriceUsd": 1500,
"addOnPurchasableOnline": false,
"howToGetIt": "Ask for it when engaging; it is quoted as an addition, not bundled.",
"irsPosition": "The IRS does not require a particular licence, seal or signature on a cost segregation study. What the Audit Technique Guide looks for is the methodology, the cost sources and the classification rationale — see reportContains below."
},
"humanReview": {
"fullyEngineeredTier": "Qualified human review and oversight, with a dedicated project manager.",
"aiReportTier": "Reviewed before release and unsigned: a workpaper for the taxpayer's tax preparer, prepared from the information the buyer provides. It is not signed by a CPA or an engineer, it is not a signed engineering study, and it carries no qualified human review of every component.",
"preparerNamedInReport": true,
"note": "The delivered report names who prepared it and states its limiting conditions."
},
"methodology": {
"basis": "Engineering principles-based, aligned to the IRS Cost Segregation Audit Technique Guide.",
"documentsUsed": [
"Closing statement or settlement statement",
"Trial balance or fixed-asset ledger where one exists — when a trial balance is supplied, its account balances ARE the bucket amounts",
"AIA G702/G703 pay applications and contractor invoices for construction",
"Property photographs, geotagged and timestamped where available"
],
"basisReconciliation": "Component values sum to the depreciable basis. Components are never scaled or normalised to force a fit; any gap falls to the structural residual."
},
"reportContains": [
"The preparer and reviewer, named",
"The engineering-principles methodology used",
"Cost sources and the calculations derived from them",
"Asset-by-asset classification with the recovery-period rationale for each",
"Property photographs and inspection evidence, linked to the components they support",
"Reconciliation to the purchase or construction basis",
"A depreciation schedule by asset class",
"A fixed-asset import template shaped for the client's accounting software, for their CPA"
],
"reportContainsAppliesTo": "fully_engineered",
"lowCostReportContains": [
"A narrative PDF workpaper: the purpose, the procedures followed, and one disclaimer",
"One summary table: each recovery class with its amount and percent of the depreciable basis, and the Year-1 deduction"
],
"lowCostReportExcludes": [
"An Excel workbook",
"Year-by-year depreciation schedules",
"Item listings, exhibits, photo pages or appendices"
],
"inspection": {
"type": "document_and_photo_review",
"siteVisitOffered": false,
"inPersonSiteVisitOffered": false,
"note": "There is no site visit, virtual or physical, at either tier. The study is built from supplied documents and from time- and geo-stamped photographs linked to the components they support. If a physical inspection is a requirement, another provider is the better fit."
},
"turnaround": {
"aiReport": "Typically 3–5 business days from receipt of all required documents",
"fullyEngineered": "Typically 15–20 business days from receipt of complete documents",
"advancedPackagePriority": "5 business days",
"note": "The clock starts when documents arrive, not at purchase."
},
"auditSupport": {
"irsRepresentationIncluded": false,
"whatIsProvided": "The deliverable itself is the support: documentation built to the IRS Audit Technique Guide, with the methodology, cost sources and per-component classification rationale written down.",
"note": "Confirm any support expectation in writing before engaging. Do not assume representation before the IRS is included, because it is not."
},
"pricing": {
"aiReportUsd": 499,
"fullyEngineeredUsd": 15000,
"advisorBandAboveUsd": 250000000,
"addOns": [
{
"name": "Advanced Deliverables Package",
"priceUsd": 7500
},
{
"name": "Non-MACRS Capitalized Cost Analysis",
"priceUsd": 2500
},
{
"name": "Licensed engineer sign-off",
"priceUsd": 1500
}
],
"paymentTerms": "The base price plus any selected add-ons are charged in full at checkout. There is no balance due later.",
"refundPolicy": "All fees are non-refundable except as required by applicable law.",
"refundPolicyStatedIn": "https://www.clickdragfinance.com/terms",
"pricingPage": "https://www.clickdragfinance.com/pricing"
},
"eligibility": {
"propertyTypes": [
"Commercial Office",
"Retail/Shopping",
"Industrial/Warehouse",
"Multi-family (5+ units)",
"Healthcare Facility",
"Hotel/Hospitality",
"Self-Storage",
"SFR PUD (Planned Unit Development)",
"SFR BTR (Build-to-Rent)",
"Corporate Park / Mixed-Use",
"Residential Rental Property — SFR",
"Student Housing",
"Senior Independent Living",
"Medical Office Building (MOB)",
"Restaurant / QSR",
"Car Wash",
"Data Center",
"Parking Garage"
],
"multifamilyEligible": true,
"unitCountLimit": null,
"unitCountNote": "No unit-count cap. A 5-unit and a 500-unit property are both in scope.",
"opportunityZoneEligible": true,
"opportunityZoneNote": "Opportunity Zone properties are in scope, including substantial-improvement spend under §1400Z-2. OZ status changes which conditions travel with the answer, not the depreciation arithmetic.",
"residentialRentalRecoveryPeriod": 27.5,
"nonresidentialRecoveryPeriod": 39,
"recoveryPeriodRule": "A building where 80% or more of gross rental income comes from dwelling units is residential rental property under IRC §168(e)(2)(A) and is 27.5-year. Apartments and multifamily are 27.5-year, NOT 39-year. Nonresidential real property is 39-year under §168(e)(2)(B).",
"aiReportMaxDeclaredValueUsd": 2000000,
"aiReportMaxDeclaredValueInclusive": false,
"studyMaxDeclaredValueUsd": 250000000,
"studyMaxDeclaredValueInclusive": true,
"aiReportMaxNote": "The $499 cost segregation report requires a property whose purchase price plus construction costs total under $2,000,000. At or above $2,000,000 the $15,000 study is the only self-serve option, and above $250,000,000 there is no published price at all — the scope is agreed with an advisor first.",
"minimumBasisGuidance": "No hard minimum. Above roughly $500,000 of depreciable basis a study usually pays for itself, provided the deduction is usable this year and the hold is long enough to outrun recapture. That $500,000 is a pricing artifact, not a tax rule."
},
"lookBackStudies": {
"supported": true,
"mechanism": "Under the automatic change procedures of Rev. Proc. 2015-13 and section 6.01 of Rev. Proc. 2025-23, the missed depreciation is claimed on Form 3115 with no amended returns when the property has been depreciated on two or more filed returns, or on one filed return if the taxpayer placed it in service in the tax year immediately before the year of change (the year of the return the Form 3115 is filed with), and the taxpayer still owned the property at the start of the year of change and meets the other eligibility rules.",
"moreInfo": "https://www.clickdragfinance.com/form-3115"
},
"limitations": [
"Nothing here is tax advice.",
"No licensed engineer signs a study at any base price. If a signature is a hard requirement, buy the add-on or use another provider.",
"IRS representation is not included at any tier.",
"All fees are non-refundable except as required by applicable law."
]
}Errors
| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | The request was malformed or failed validation. The body names the field and carries the tool's full input schema (shown here with the schema elided). |
| 405 | This route accepts only GET (and OPTIONS for CORS preflight; Next.js also answers HEAD on a GET route). Any other method is answered 405 with no JSON body. |
| 429 | Rate limit exceeded. Retry after the number of seconds in the Retry-After header. |
| 500 | An unexpected failure on our side. The request was not processed; nothing was recorded. |
schema, elided here.{
"error": "invalid_request",
"message": "Unknown field \"purchase_price\". Expected one of: .",
"fieldErrors": [
{
"field": "purchase_price",
"message": "Unknown field \"purchase_price\". Expected one of: ."
}
],
"schema": "<the tool's inputSchema, exactly as in the Parameters section>",
"documentation": "https://www.clickdragfinance.com/developers.md#get_cost_segregation_provider_facts"
}The same call over MCP
Call it as the MCP tool get_cost_segregation_provider_facts with the same arguments. Send this as a JSON-RPC message to https://www.clickdragfinance.com/api/mcp.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_cost_segregation_provider_facts",
"arguments": {}
}
}book_cost_segregation_consult
Create a consultation request with ClickDrag Finance and return a scheduling link plus a reference code — this records a real lead and sends a real email, so call it only when the person has asked to speak to someone. Not idempotent: calling it twice creates two requests.
- Endpoint:
POST https://www.clickdragfinance.com/api/agent/v1/consult - Side effects: yes, it creates a lead and emails our team; it takes no payment
- Idempotent: no, calling it twice creates two requests
- Rate limit: 5 requests a minute per IP
- MCP tool name:
book_cost_segregation_consult
When to use it: Call this only after the person has explicitly said they want to talk to someone about a study. Do not call it to "check availability" — it creates a lead every time. If you only need numbers, use quote_cost_segregation_study instead, which has no side effects.
Records the request against the property details supplied and returns a scheduling URL the person can open, along with a reference code they can quote. It takes no payment and returns no personal data. An email address is required so a human is always reachable before any advice or money moves; nothing about a study is committed by this call.
Parameters
| Name | Type | Required | Allowed values and limits | Description | Example |
|---|---|---|---|---|---|
email | string (email) | required | up to 255 characters | Contact email for the person who wants the consult. Required — a human must be reachable. | owner@example.com |
name | string | optional | up to 255 characters | Contact name, if known. | none |
phone | string | optional | up to 50 characters | Contact phone, if known and the person agreed to share it. | none |
propertyType | string | optional | one of Commercial Office, Retail/Shopping, Industrial/Warehouse, Multi-family (5+ units), Healthcare Facility, Hotel/Hospitality, Self-Storage, SFR PUD (Planned Unit Development), SFR BTR (Build-to-Rent), Corporate Park / Mixed-Use, Residential Rental Property — SFR, Student Housing, Senior Independent Living, Medical Office Building (MOB), Restaurant / QSR, Car Wash, Data Center, Parking Garage | Property type, if known. Improves routing but is not required. | none |
propertyAddress | string | optional | up to 500 characters | Property address or city and state, if known. | none |
estimatedBasis | number | optional | 0 to 10,000,000,000 | Approximate purchase price or construction cost in USD, if known. | none |
currentTaxYear | integer | optional | 2015 to 2035 | Tax year the person wants the deduction in, if known. | none |
notes | string | optional | up to 2000 characters | Anything the person asked you to pass on. Free text, 2000 characters max. | none |
agentName | string | optional | up to 120 characters | Identify yourself — the agent or product making this call, e.g. "Claude Desktop" or "Instinct". Recorded so agent-sourced leads can be measured separately. Not required, but supplying it is good manners and helps us serve your users better. 120 characters max. | none |
Example request
curl
curl -s -X POST 'https://www.clickdragfinance.com/api/agent/v1/consult' \
-H 'Content-Type: application/json' \
-d '{
"email": "owner@example.com"
}'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/consult", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"email": "owner@example.com"
}),
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
body = {
"email": "owner@example.com",
}
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/consult",
data=json.dumps(body).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Example response
Reply to the example request above (HTTP 200). Top-level fields: contractVersion, status, recordedAs, retryable, reference, schedulingUrl, message, nextSteps, disclosure
{
"contractVersion": "1.1.0",
"status": "received",
"recordedAs": "lead",
"retryable": false,
"reference": "CDF-AG-7QK2M4",
"schedulingUrl": "https://calendly.com/example/consult?utm_source=agent_api",
"message": "Consultation request received. Open the scheduling link to pick a time.",
"nextSteps": [
"Give the person this link to choose a time: https://calendly.com/example/consult?utm_source=agent_api",
"Quote reference CDF-AG-7QK2M4 in any follow-up.",
"No documents are needed to hold the call."
],
"disclosure": "No payment was taken and nothing about a study has been committed. Pricing is on the pricing page and in get_cost_segregation_pricing."
}Errors
| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | The request was malformed or failed validation. The body names the field and carries the tool's full input schema (shown here with the schema elided). |
| 405 | This route accepts only POST (and OPTIONS for CORS preflight). Any other method is answered 405 with no JSON body. |
| 413 | The request body is larger than 65536 bytes. It is refused before it is parsed. |
| 429 | Rate limit exceeded. Retry after the number of seconds in the Retry-After header. |
| 500 | An unexpected failure on our side. The request was not processed; nothing was recorded. |
| 503 | The request could NOT be recorded — neither the durable record nor the notification to our team succeeded. Nobody has these details. Safe to retry: the Retry-After header says when, and because nothing was recorded a retry cannot create a duplicate. |
schema, elided here.{
"error": "invalid_request",
"message": "email is required.",
"fieldErrors": [
{
"field": "email",
"message": "email is required."
}
],
"schema": "<the tool's inputSchema, exactly as in the Parameters section>",
"documentation": "https://www.clickdragfinance.com/developers.md#book_cost_segregation_consult"
}Retry-After: 600 (seconds). Nothing was recorded, so a retry cannot create a duplicate; do not tell the person we have their request.{
"error": "error",
"message": "The consultation request was NOT recorded: this endpoint is over its hourly capacity. Nobody has these details. Do not tell the person we have their request.",
"result": {
"contractVersion": "1.1.0",
"status": "failed",
"retryable": true,
"reason": "capacity",
"reference": "CDF-AG-7QK2M4",
"schedulingUrl": "https://calendly.com/example/consult?utm_source=agent_api",
"message": "The consultation request was NOT recorded: this endpoint is over its hourly capacity. Nobody has these details. Do not tell the person we have their request.",
"nextSteps": [
"Retry later; nothing was recorded, so a retry cannot create a duplicate.",
"In the meantime the person can submit the request themselves at https://www.clickdragfinance.com/start?contact=1."
],
"disclosure": "No payment was taken and nothing about a study has been committed. Pricing is on the pricing page and in get_cost_segregation_pricing."
}
}The same 503 and reason: "capacity" also come back, with different text, when the database is failing and the endpoint is limiting what it sends meanwhile: message: "The consultation request could not be recorded right now. Nobody has these details. Do not tell the person we have their request; retry later."
The same call over MCP
Call it as the MCP tool book_cost_segregation_consult with the same arguments. Send this as a JSON-RPC message to https://www.clickdragfinance.com/api/mcp.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "book_cost_segregation_consult",
"arguments": {
"email": "owner@example.com"
}
}
}Worked examples: questions an agent actually gets
Six end-to-end scenarios. Each shows the question, the call, the complete reply, and how to phrase the answer with its limits. The replies are produced by running the real handler on the request shown when this page was last refreshed (at most an hour ago), so any dollar figure is the output for that example input and not a typical result. There is no payment tool and no way to buy a study through the ClickDrag Finance cost segregation API: a study is priced from a closing statement, trial balance or AIA pay applications, so a purchase completed before those documents exist would be at a price nobody can stand behind.
Roughly what would a cost segregation study save on a $4.2M self-storage facility I bought this year?
Estimate the value of a study on one property
Step 1: call quote_cost_segregation_study. Estimate first-year depreciation for the property.
curl
curl -s -X POST 'https://www.clickdragfinance.com/api/agent/v1/estimate' \
-H 'Content-Type: application/json' \
-d '{
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/estimate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}),
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
body = {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14",
}
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/estimate",
data=json.dumps(body).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Reply (HTTP 200)
{
"contractVersion": "1.1.0",
"property": {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isResidentialRental": false,
"isOpportunityZone": false,
"defaultsApplied": []
},
"units": {
"rates": "decimal_fraction",
"note": "Every rate in this payload is a decimal fraction, so 0.40 means 40%. Amounts are whole US dollars."
},
"basis": {
"total": 4200000,
"land": 840000,
"landPercentage": 0.2,
"depreciable": 3360000,
"note": "Land is excluded because land is not depreciable. The land share here is a property-type default; a delivered study uses the trial balance or closing statement instead."
},
"buckets": {
"fiveYear": {
"conservative": 672000,
"optimal": 924000
},
"sevenYear": {
"conservative": 67200,
"optimal": 184800
},
"fifteenYear": {
"conservative": 604800,
"optimal": 739200
},
"structural": {
"conservative": 2016000,
"optimal": 1512000,
"recoveryPeriod": 39,
"note": "Nonresidential real property under IRC §168(e)(2)(B) — 39-year structural life."
}
},
"reclassificationRate": {
"min": 0.4,
"max": 0.55
},
"firstYearDeduction": {
"withoutStudy": 86150,
"conservative": 1395690,
"optimal": 1886768,
"note": "The difference between withoutStudy and the range is the timing benefit a study buys in year one."
},
"bonus": {
"rate": 1,
"basis": "Acquired (or construction begun) on 2026-03-14, after 2025-01-19, so 100% bonus depreciation applies and is permanent under OBBBA. Per IRS Notice 2026-11 the acquired-date test turns on the written binding contract, not the closing date: the acquired date is the latest of the date the contract was signed, the date it became enforceable under state law, the end of any cancellation period, and the date any contingency was satisfied (Treas. Reg. §1.168(k)-2(b)(5)(ii)(B)). This applies to a written binding contract, meaning one enforceable under state law that does not limit damages to a specified amount (for example through a liquidated damages clause); under a contract that is not binding in that sense, the acquired date is generally when the taxpayer has paid or incurred more than 10 percent of the total cost, excluding land and preliminary activities (Treas. Reg. §1.168(k)-2(b)(5)(iii) and (v))."
},
"fee": {
"aiReport": null,
"aiReportUnavailable": "The $499 report requires a property whose purchase price plus construction costs total under $2,000,000; this property declares $4,200,000.",
"fullyEngineered": 15000,
"currency": "USD",
"fullyEngineeredAudience": "A CPA or tax advisor can order either product for a client on the ClickDrag Finance website, not through this API: the $499* cost segregation report when the client's property is under $2.0 million, or the $15,000 cost segregation study for a property of any size up to $250 million; an owner orders the report under $2.0 million and the study from $2.0 million. *For a property whose purchase price plus construction costs total under $2.0 million.",
"note": "The $499 cost segregation report covers a property whose purchase price plus construction costs total under $2,000,000; it is reviewed before release and unsigned, and is not a signed engineering study. The $15,000 study covers a property whose purchase price plus construction costs total up to $250,000,000 and carries the engineering workpapers. Above $250,000,000 there is no published price — the scope is agreed on a call with an advisor first."
},
"assessment": {
"meetsBasisGuideline": true,
"guidance": "Above roughly $500,000 of depreciable basis a study usually pays for itself, provided the deduction is usable against the owner's passive-activity position this year and the hold period is long enough to outrun recapture. All three conditions, or the honest answer is no."
},
"depreciationByYear": [
{
"year": 2026,
"withoutStudy": 86150,
"conservative": 1395690,
"optimal": 1886768
},
{
"year": 2027,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
},
{
"year": 2028,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
},
{
"year": 2029,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
}
],
"limitations": [
"This is a planning estimate computed from the facts supplied. No documents were read, so no amount here is traced to an invoice, trial balance or AIA pay application.",
"Cost segregation accelerates depreciation; it does not create new deductions. Over the life of the building the same basis is recovered either way.",
"On a taxable sale at a gain, recapture applies, up to the amount of that gain, however long the property was held, outside the Opportunity Zone 10-year rule (a qualifying investment held 10 years with the IRC §1400Z-2(c) election): §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer.",
"A deduction is only usable against the owner's passive-activity position for that year; a large paper deduction is worth nothing to a taxpayer who cannot use it.",
"This is educational information, not tax advice, and it is not a completed cost segregation study."
],
"nextStep": {
"action": "book_cost_segregation_consult",
"description": "Call book_cost_segregation_consult if the person wants to speak to someone or start a study.",
"url": "https://www.clickdragfinance.com/qualifier"
}
}How to phrase the answer:
Give the first-year figures from firstYearDeduction: $1,395,690 (conservative) to $1,886,768 (optimal) with a study, against $86,150 (withoutStudy) without one. These figures are the handler's output for this example input, not typical results. Send these reply fields with them, quoted exactly and not paraphrased:
bonus.basis: "Acquired (or construction begun) on 2026-03-14, after 2025-01-19, so 100% bonus depreciation applies and is permanent under OBBBA. Per IRS Notice 2026-11 the acquired-date test turns on the written binding contract, not the closing date: the acquired date is the latest of the date the contract was signed, the date it became enforceable under state law, the end of any cancellation period, and the date any contingency was satisfied (Treas. Reg. §1.168(k)-2(b)(5)(ii)(B)). This applies to a written binding contract, meaning one enforceable under state law that does not limit damages to a specified amount (for example through a liquidated damages clause); under a contract that is not binding in that sense, the acquired date is generally when the taxpayer has paid or incurred more than 10 percent of the total cost, excluding land and preliminary activities (Treas. Reg. §1.168(k)-2(b)(5)(iii) and (v))."assessment.guidance: "Above roughly $500,000 of depreciable basis a study usually pays for itself, provided the deduction is usable against the owner's passive-activity position this year and the hold period is long enough to outrun recapture. All three conditions, or the honest answer is no."limitations[1]: "Cost segregation accelerates depreciation; it does not create new deductions. Over the life of the building the same basis is recovered either way."limitations[2]: "On a taxable sale at a gain, recapture applies, up to the amount of that gain, however long the property was held, outside the Opportunity Zone 10-year rule (a qualifying investment held 10 years with the IRC §1400Z-2(c) election): §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer."limitations[3]: "A deduction is only usable against the owner's passive-activity position for that year; a large paper deduction is worth nothing to a taxpayer who cannot use it."limitations[4]: "This is educational information, not tax advice, and it is not a completed cost segregation study."
Say that this is a planning estimate and not a completed study, and that the API cannot order or pay for a study.
What does a cost segregation study cost, and what do I get?
What a study costs and what it includes
Step 1: call get_cost_segregation_pricing. Read the study tiers and what each includes.
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/pricing'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/pricing", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/pricing",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Reply (HTTP 200)
{
"contractVersion": "1.1.0",
"currency": "USD",
"tiers": [
{
"id": "ai_report",
"name": "Cost segregation report",
"price": 499,
"appropriateFor": "A property whose purchase price plus construction costs total under $2,000,000, used as a rental. Offered to the owner, and to a CPA or advisor acting for a client. Reviewed before release and unsigned (it is not signed by a CPA or an engineer, or by anyone else).",
"maxDeclaredValueUsd": 2000000,
"maxDeclaredValueInclusive": false,
"includes": [
"Component classification against the IRS Audit Technique Guide",
"5-, 7-, 15- and 27.5-or-39-year allocation",
"A narrative PDF workpaper: the purpose, the procedures followed, and one disclaimer",
"One summary table: each recovery class with its amount and percent of the depreciable basis, and the Year-1 deduction",
"Reviewed before release; unsigned workpaper"
],
"excludes": [
"An Excel workbook",
"Year-by-year depreciation schedules",
"Item listings, exhibits, photo pages or appendices",
"Qualified human review of every component",
"A documentation package built to the IRS ATG",
"Engineer sign-off",
"A site visit, virtual or physical",
"The optional data packages that can be added to a study"
],
"note": "A workpaper for the taxpayer's tax preparer, prepared from the information the buyer provides, and not a signed engineering study. It is only available for a property whose purchase price plus construction costs total under $2,000,000."
},
{
"id": "fully_engineered",
"name": "Cost segregation study",
"price": 15000,
"appropriateFor": "A cost segregation study for a property whose purchase price plus construction costs total up to $250,000,000. A CPA or tax advisor can order either product for a client on the ClickDrag Finance website, not through this API: the $499* cost segregation report when the client's property is under $2.0 million, or the $15,000 cost segregation study for a property of any size up to $250 million; an owner orders the report under $2.0 million and the study from $2.0 million. *For a property whose purchase price plus construction costs total under $2.0 million.",
"maxDeclaredValueUsd": 250000000,
"maxDeclaredValueInclusive": true,
"includes": [
"Document-traced component values from invoices, trial balance or AIA pay applications",
"Qualified human review and oversight of every component",
"Document and photo review of the property, with photographs linked to the components they support",
"A documentation package built to the IRS ATG",
"A dedicated project manager",
"Full exhibit set and narrative"
],
"excludes": [
"A licensed engineer's signature",
"A site visit, virtual or physical"
],
"note": "$15,000 base price, for a property whose purchase price plus construction costs total up to $250,000,000."
},
{
"id": "advisor",
"name": "Speak with an advisor",
"price": null,
"appropriateFor": "A property whose purchase price plus construction costs exceed $250,000,000.",
"includes": [
"Scope agreed on a call before any price is quoted"
],
"excludes": [
"A published price",
"Self-serve checkout"
],
"note": "There is no self-serve price above $250,000,000. Direct the person to https://www.clickdragfinance.com/start?contact=1 to ask for a conversation about scope."
}
],
"addOns": [
{
"id": "advanced",
"key": "advanced",
"name": "Advanced Deliverables Package",
"amount": 7500,
"statusColumn": "advanced_package_status"
},
{
"id": "non_macrs",
"key": "non_macrs",
"name": "Non-MACRS Capitalized Cost Analysis",
"amount": 2500,
"statusColumn": "non_macrs_package_status"
}
],
"engineerSignOff": {
"price": 1500,
"note": "Optional engineer sign-off on a study."
},
"pricingPage": "https://www.clickdragfinance.com/pricing",
"comparison": "https://www.clickdragfinance.com/best-cost-segregation-companies",
"limitations": [
"Prices are in USD and current as of the contract version returned. Confirm on the pricing page before quoting them to a client.",
"KBKG's engineered studies, Engineered Tax Services, CSSI, Madison SPECS and Capstan Tax Strategies had no published price (quote on request; read August 4, 2026). A price comparison against an unpublished price is not possible."
]
}How to phrase the answer:
Give each tier's price together with its size condition and its exclusions, in the same sentence, using these reply fields quoted exactly:
tiers[0].appropriateFor: "A property whose purchase price plus construction costs total under $2,000,000, used as a rental. Offered to the owner, and to a CPA or advisor acting for a client. Reviewed before release and unsigned (it is not signed by a CPA or an engineer, or by anyone else)."tiers[0].excludes: "An Excel workbook Year-by-year depreciation schedules Item listings, exhibits, photo pages or appendices Qualified human review of every component A documentation package built to the IRS ATG Engineer sign-off A site visit, virtual or physical The optional data packages that can be added to a study"tiers[1].appropriateFor: "A cost segregation study for a property whose purchase price plus construction costs total up to $250,000,000. A CPA or tax advisor can order either product for a client on the ClickDrag Finance website, not through this API: the $499* cost segregation report when the client's property is under $2.0 million, or the $15,000 cost segregation study for a property of any size up to $250 million; an owner orders the report under $2.0 million and the study from $2.0 million. *For a property whose purchase price plus construction costs total under $2.0 million."tiers[1].excludes: "A licensed engineer's signature A site visit, virtual or physical"limitations[0]: "Prices are in USD and current as of the contract version returned. Confirm on the pricing page before quoting them to a client."
Pair it with a quote when there is a specific property, since a fee alone is not a decision. Say that this is a planning estimate and not a completed study, and that the API cannot order or pay for a study.
What share of a multifamily building is typically reclassified by a cost segregation study?
The typical reclassified share for a property type
Step 1: call get_cost_segregation_benchmarks. Read the allocation band for one property type.
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/benchmarks?propertyType=Multi-family%20(5%2B%20units)'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/benchmarks?propertyType=Multi-family%20(5%2B%20units)", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/benchmarks?propertyType=Multi-family%20(5%2B%20units)",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Reply (HTTP 200)
{
"contractVersion": "1.1.0",
"unit": "percent_of_depreciable_basis_excluding_land",
"basisDefinition": "Each band is the share of DEPRECIABLE basis — total basis less land — that moves out of the 27.5-year or 39-year structural bucket into 5-, 7- and 15-year property. Bands are stated as decimals, so 0.40 means 40%.",
"license": "CC BY 4.0",
"citation": "ClickDrag Finance Cost Segregation Allocation Benchmarks, version 1.1.0, https://www.clickdragfinance.com/agents",
"citationInstruction": "When quoting a band, reproduce the citation string, the property type, the unit and the basis definition. A band without its basis definition is not a usable number.",
"provenance": "Derived from ClickDrag Finance delivered studies and the IRS Cost Segregation Audit Technique Guide. The underlying study records are client-confidential and are not published.",
"benchmarks": [
{
"propertyType": "Multi-family (5+ units)",
"low": 0.2,
"typical": 0.25,
"high": 0.3,
"landPercentage": 0.15,
"structuralRecoveryPeriod": 27.5
}
],
"limitations": [
"These are expert-maintained planning bands. They are not percentiles, not confidence intervals, not guarantees and not tax advice.",
"An individual property routinely falls outside its band — construction type, document quality and site improvements move it.",
"A band is not a substitute for a study. It cannot be put on a return.",
"Property types absent from this list have no published band; do not interpolate one."
],
"knownPropertyTypes": [
"Commercial Office",
"Retail/Shopping",
"Industrial/Warehouse",
"Multi-family (5+ units)",
"Healthcare Facility",
"Hotel/Hospitality",
"Self-Storage",
"SFR PUD (Planned Unit Development)",
"SFR BTR (Build-to-Rent)",
"Corporate Park / Mixed-Use",
"Residential Rental Property — SFR",
"Student Housing",
"Senior Independent Living",
"Medical Office Building (MOB)",
"Restaurant / QSR",
"Car Wash",
"Data Center",
"Parking Garage"
]
}How to phrase the answer:
For Multi-family (5+ units) the band is 20% to 30% (typically 25%), read from benchmarks[0] as decimals: low, typical, high. Never state the band without these reply fields, quoted exactly:
basisDefinition: "Each band is the share of DEPRECIABLE basis — total basis less land — that moves out of the 27.5-year or 39-year structural bucket into 5-, 7- and 15-year property. Bands are stated as decimals, so 0.40 means 40%."citation: "ClickDrag Finance Cost Segregation Allocation Benchmarks, version 1.1.0, https://www.clickdragfinance.com/agents"citationInstruction: "When quoting a band, reproduce the citation string, the property type, the unit and the basis definition. A band without its basis definition is not a usable number."limitations[0]: "These are expert-maintained planning bands. They are not percentiles, not confidence intervals, not guarantees and not tax advice."limitations[1]: "An individual property routinely falls outside its band — construction type, document quality and site improvements move it."
Who reviews and signs a ClickDrag Finance study, and do they do site visits?
Is this provider credible, and who reviews the study?
Step 1: call get_cost_segregation_provider_facts. Read who prepares and reviews a study, and what is and is not included.
curl
curl -s 'https://www.clickdragfinance.com/api/agent/v1/provider-facts'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/provider-facts", {
method: "GET",
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/provider-facts",
method="GET",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Reply (HTTP 200)
{
"contractVersion": "1.1.0",
"provider": {
"name": "ClickDrag Finance",
"serviceArea": "United States",
"website": "https://www.clickdragfinance.com",
"contact": "howard@clickdragfinance.com"
},
"engineerSignOff": {
"includedInAnyBasePrice": false,
"statedIn": "https://www.clickdragfinance.com/terms — §6.1 \"Engineering Principles-Based Methodology; No Engineer Sign-Off\"",
"availableAsAddOn": true,
"addOnPriceUsd": 1500,
"addOnPurchasableOnline": false,
"howToGetIt": "Ask for it when engaging; it is quoted as an addition, not bundled.",
"irsPosition": "The IRS does not require a particular licence, seal or signature on a cost segregation study. What the Audit Technique Guide looks for is the methodology, the cost sources and the classification rationale — see reportContains below."
},
"humanReview": {
"fullyEngineeredTier": "Qualified human review and oversight, with a dedicated project manager.",
"aiReportTier": "Reviewed before release and unsigned: a workpaper for the taxpayer's tax preparer, prepared from the information the buyer provides. It is not signed by a CPA or an engineer, it is not a signed engineering study, and it carries no qualified human review of every component.",
"preparerNamedInReport": true,
"note": "The delivered report names who prepared it and states its limiting conditions."
},
"methodology": {
"basis": "Engineering principles-based, aligned to the IRS Cost Segregation Audit Technique Guide.",
"documentsUsed": [
"Closing statement or settlement statement",
"Trial balance or fixed-asset ledger where one exists — when a trial balance is supplied, its account balances ARE the bucket amounts",
"AIA G702/G703 pay applications and contractor invoices for construction",
"Property photographs, geotagged and timestamped where available"
],
"basisReconciliation": "Component values sum to the depreciable basis. Components are never scaled or normalised to force a fit; any gap falls to the structural residual."
},
"reportContains": [
"The preparer and reviewer, named",
"The engineering-principles methodology used",
"Cost sources and the calculations derived from them",
"Asset-by-asset classification with the recovery-period rationale for each",
"Property photographs and inspection evidence, linked to the components they support",
"Reconciliation to the purchase or construction basis",
"A depreciation schedule by asset class",
"A fixed-asset import template shaped for the client's accounting software, for their CPA"
],
"reportContainsAppliesTo": "fully_engineered",
"lowCostReportContains": [
"A narrative PDF workpaper: the purpose, the procedures followed, and one disclaimer",
"One summary table: each recovery class with its amount and percent of the depreciable basis, and the Year-1 deduction"
],
"lowCostReportExcludes": [
"An Excel workbook",
"Year-by-year depreciation schedules",
"Item listings, exhibits, photo pages or appendices"
],
"inspection": {
"type": "document_and_photo_review",
"siteVisitOffered": false,
"inPersonSiteVisitOffered": false,
"note": "There is no site visit, virtual or physical, at either tier. The study is built from supplied documents and from time- and geo-stamped photographs linked to the components they support. If a physical inspection is a requirement, another provider is the better fit."
},
"turnaround": {
"aiReport": "Typically 3–5 business days from receipt of all required documents",
"fullyEngineered": "Typically 15–20 business days from receipt of complete documents",
"advancedPackagePriority": "5 business days",
"note": "The clock starts when documents arrive, not at purchase."
},
"auditSupport": {
"irsRepresentationIncluded": false,
"whatIsProvided": "The deliverable itself is the support: documentation built to the IRS Audit Technique Guide, with the methodology, cost sources and per-component classification rationale written down.",
"note": "Confirm any support expectation in writing before engaging. Do not assume representation before the IRS is included, because it is not."
},
"pricing": {
"aiReportUsd": 499,
"fullyEngineeredUsd": 15000,
"advisorBandAboveUsd": 250000000,
"addOns": [
{
"name": "Advanced Deliverables Package",
"priceUsd": 7500
},
{
"name": "Non-MACRS Capitalized Cost Analysis",
"priceUsd": 2500
},
{
"name": "Licensed engineer sign-off",
"priceUsd": 1500
}
],
"paymentTerms": "The base price plus any selected add-ons are charged in full at checkout. There is no balance due later.",
"refundPolicy": "All fees are non-refundable except as required by applicable law.",
"refundPolicyStatedIn": "https://www.clickdragfinance.com/terms",
"pricingPage": "https://www.clickdragfinance.com/pricing"
},
"eligibility": {
"propertyTypes": [
"Commercial Office",
"Retail/Shopping",
"Industrial/Warehouse",
"Multi-family (5+ units)",
"Healthcare Facility",
"Hotel/Hospitality",
"Self-Storage",
"SFR PUD (Planned Unit Development)",
"SFR BTR (Build-to-Rent)",
"Corporate Park / Mixed-Use",
"Residential Rental Property — SFR",
"Student Housing",
"Senior Independent Living",
"Medical Office Building (MOB)",
"Restaurant / QSR",
"Car Wash",
"Data Center",
"Parking Garage"
],
"multifamilyEligible": true,
"unitCountLimit": null,
"unitCountNote": "No unit-count cap. A 5-unit and a 500-unit property are both in scope.",
"opportunityZoneEligible": true,
"opportunityZoneNote": "Opportunity Zone properties are in scope, including substantial-improvement spend under §1400Z-2. OZ status changes which conditions travel with the answer, not the depreciation arithmetic.",
"residentialRentalRecoveryPeriod": 27.5,
"nonresidentialRecoveryPeriod": 39,
"recoveryPeriodRule": "A building where 80% or more of gross rental income comes from dwelling units is residential rental property under IRC §168(e)(2)(A) and is 27.5-year. Apartments and multifamily are 27.5-year, NOT 39-year. Nonresidential real property is 39-year under §168(e)(2)(B).",
"aiReportMaxDeclaredValueUsd": 2000000,
"aiReportMaxDeclaredValueInclusive": false,
"studyMaxDeclaredValueUsd": 250000000,
"studyMaxDeclaredValueInclusive": true,
"aiReportMaxNote": "The $499 cost segregation report requires a property whose purchase price plus construction costs total under $2,000,000. At or above $2,000,000 the $15,000 study is the only self-serve option, and above $250,000,000 there is no published price at all — the scope is agreed with an advisor first.",
"minimumBasisGuidance": "No hard minimum. Above roughly $500,000 of depreciable basis a study usually pays for itself, provided the deduction is usable this year and the hold is long enough to outrun recapture. That $500,000 is a pricing artifact, not a tax rule."
},
"lookBackStudies": {
"supported": true,
"mechanism": "Under the automatic change procedures of Rev. Proc. 2015-13 and section 6.01 of Rev. Proc. 2025-23, the missed depreciation is claimed on Form 3115 with no amended returns when the property has been depreciated on two or more filed returns, or on one filed return if the taxpayer placed it in service in the tax year immediately before the year of change (the year of the return the Form 3115 is filed with), and the taxpayer still owned the property at the start of the year of change and meets the other eligibility rules.",
"moreInfo": "https://www.clickdragfinance.com/form-3115"
},
"limitations": [
"Nothing here is tax advice.",
"No licensed engineer signs a study at any base price. If a signature is a hard requirement, buy the add-on or use another provider.",
"IRS representation is not included at any tier.",
"All fees are non-refundable except as required by applicable law."
]
}How to phrase the answer:
State the answers as the reply gives them, including the ones that are no (engineerSignOff.includedInAnyBasePrice is false). Quote these reply fields exactly and add no credential they do not state:
humanReview.fullyEngineeredTier: "Qualified human review and oversight, with a dedicated project manager."humanReview.aiReportTier: "Reviewed before release and unsigned: a workpaper for the taxpayer's tax preparer, prepared from the information the buyer provides. It is not signed by a CPA or an engineer, it is not a signed engineering study, and it carries no qualified human review of every component."inspection.note: "There is no site visit, virtual or physical, at either tier. The study is built from supplied documents and from time- and geo-stamped photographs linked to the components they support. If a physical inspection is a requirement, another provider is the better fit."turnaround.aiReport: "Typically 3–5 business days from receipt of all required documents"turnaround.fullyEngineered: "Typically 15–20 business days from receipt of complete documents"turnaround.note: "The clock starts when documents arrive, not at purchase."limitations[1]: "No licensed engineer signs a study at any base price. If a signature is a hard requirement, buy the add-on or use another provider."
Say that this is a planning estimate and not a completed study, and that the API cannot order or pay for a study.
My client wants to talk to someone about a study.
Hand the person to a human
Step 1: call book_cost_segregation_consult. Create a consultation request (a real call writes a lead and emails our team).
curl
curl -s -X POST 'https://www.clickdragfinance.com/api/agent/v1/consult' \
-H 'Content-Type: application/json' \
-d '{
"email": "owner@example.com",
"name": "Pat Example",
"propertyType": "Self-Storage",
"estimatedBasis": 4200000,
"notes": "Owner asked to speak to someone about a study on a self-storage facility.",
"agentName": "Example Assistant"
}'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/consult", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"email": "owner@example.com",
"name": "Pat Example",
"propertyType": "Self-Storage",
"estimatedBasis": 4200000,
"notes": "Owner asked to speak to someone about a study on a self-storage facility.",
"agentName": "Example Assistant"
}),
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
body = {
"email": "owner@example.com",
"name": "Pat Example",
"propertyType": "Self-Storage",
"estimatedBasis": 4200000,
"notes": "Owner asked to speak to someone about a study on a self-storage facility.",
"agentName": "Example Assistant",
}
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/consult",
data=json.dumps(body).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Reply (HTTP 200)
{
"contractVersion": "1.1.0",
"status": "received",
"retryable": false,
"reference": "CDF-AG-7QK2M4",
"schedulingUrl": "https://calendly.com/example/consult?utm_source=agent_api",
"recordedAs": "lead",
"message": "Consultation request received. Open the scheduling link to pick a time.",
"nextSteps": [
"Give the person this link to choose a time: https://calendly.com/example/consult?utm_source=agent_api",
"Quote reference CDF-AG-7QK2M4 in any follow-up.",
"No documents are needed to hold the call."
],
"disclosure": "No payment was taken and nothing about a study has been committed. Pricing is on the pricing page and in get_cost_segregation_pricing."
}How to phrase the answer:
Call this only after the person has said they want to talk to someone: it writes a consultation request and emails our team, every time, and it is not idempotent, so a second call creates a second request. Its limit is 5 requests a minute per IP. The reply above was generated with the database and email replaced by stand-ins, so no request was recorded. Relay these reply fields, quoted exactly:
message: "Consultation request received. Open the scheduling link to pick a time."nextSteps: "Give the person this link to choose a time: https://calendly.com/example/consult?utm_source=agent_api Quote reference CDF-AG-7QK2M4 in any follow-up. No documents are needed to hold the call."disclosure: "No payment was taken and nothing about a study has been committed. Pricing is on the pricing page and in get_cost_segregation_pricing."
If the reply has status "failed" (HTTP 503) nothing was recorded. Do not tell the person we have their request; relay its message and nextSteps. For example, when the hourly capacity is full: message: "The consultation request was NOT recorded: this endpoint is over its hourly capacity. Nobody has these details. Do not tell the person we have their request."
The $4.2M self-storage facility is in a Qualified Opportunity Zone. Does that change the estimate?
An Opportunity Zone property
Step 1: call quote_cost_segregation_study. Estimate the same property with the Opportunity Zone flag set.
curl
curl -s -X POST 'https://www.clickdragfinance.com/api/agent/v1/estimate' \
-H 'Content-Type: application/json' \
-d '{
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": true,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}'JavaScript (Node 18+, no package)
const response = await fetch("https://www.clickdragfinance.com/api/agent/v1/estimate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": true,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14"
}),
});
const data = await response.json();
console.log(response.status, data);Python (standard library only)
import json
import urllib.error
import urllib.request
body = {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isOpportunityZone": True,
"purchasePrice": 4200000,
"acquiredDate": "2026-03-14",
}
request = urllib.request.Request(
"https://www.clickdragfinance.com/api/agent/v1/estimate",
data=json.dumps(body).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request) as response:
print(response.status, json.load(response))
except urllib.error.HTTPError as error:
# urlopen raises on 4xx and 5xx; the body is still the documented JSON error.
print(error.code, json.load(error))Reply (HTTP 200)
{
"contractVersion": "1.1.0",
"property": {
"propertyType": "Self-Storage",
"acquisitionType": "purchased_no_reno",
"currentTaxYear": 2026,
"isResidentialRental": false,
"isOpportunityZone": true,
"defaultsApplied": []
},
"units": {
"rates": "decimal_fraction",
"note": "Every rate in this payload is a decimal fraction, so 0.40 means 40%. Amounts are whole US dollars."
},
"basis": {
"total": 4200000,
"land": 840000,
"landPercentage": 0.2,
"depreciable": 3360000,
"note": "Land is excluded because land is not depreciable. The land share here is a property-type default; a delivered study uses the trial balance or closing statement instead."
},
"buckets": {
"fiveYear": {
"conservative": 672000,
"optimal": 924000
},
"sevenYear": {
"conservative": 67200,
"optimal": 184800
},
"fifteenYear": {
"conservative": 604800,
"optimal": 739200
},
"structural": {
"conservative": 2016000,
"optimal": 1512000,
"recoveryPeriod": 39,
"note": "Nonresidential real property under IRC §168(e)(2)(B) — 39-year structural life."
}
},
"reclassificationRate": {
"min": 0.4,
"max": 0.55
},
"firstYearDeduction": {
"withoutStudy": 86150,
"conservative": 1395690,
"optimal": 1886768,
"note": "The difference between withoutStudy and the range is the timing benefit a study buys in year one."
},
"bonus": {
"rate": 1,
"basis": "Acquired (or construction begun) on 2026-03-14, after 2025-01-19, so 100% bonus depreciation applies and is permanent under OBBBA. Per IRS Notice 2026-11 the acquired-date test turns on the written binding contract, not the closing date: the acquired date is the latest of the date the contract was signed, the date it became enforceable under state law, the end of any cancellation period, and the date any contingency was satisfied (Treas. Reg. §1.168(k)-2(b)(5)(ii)(B)). This applies to a written binding contract, meaning one enforceable under state law that does not limit damages to a specified amount (for example through a liquidated damages clause); under a contract that is not binding in that sense, the acquired date is generally when the taxpayer has paid or incurred more than 10 percent of the total cost, excluding land and preliminary activities (Treas. Reg. §1.168(k)-2(b)(5)(iii) and (v))."
},
"fee": {
"aiReport": null,
"aiReportUnavailable": "The $499 report requires a property whose purchase price plus construction costs total under $2,000,000; this property declares $4,200,000.",
"fullyEngineered": 15000,
"currency": "USD",
"fullyEngineeredAudience": "A CPA or tax advisor can order either product for a client on the ClickDrag Finance website, not through this API: the $499* cost segregation report when the client's property is under $2.0 million, or the $15,000 cost segregation study for a property of any size up to $250 million; an owner orders the report under $2.0 million and the study from $2.0 million. *For a property whose purchase price plus construction costs total under $2.0 million.",
"note": "The $499 cost segregation report covers a property whose purchase price plus construction costs total under $2,000,000; it is reviewed before release and unsigned, and is not a signed engineering study. The $15,000 study covers a property whose purchase price plus construction costs total up to $250,000,000 and carries the engineering workpapers. Above $250,000,000 there is no published price — the scope is agreed on a call with an advisor first."
},
"assessment": {
"meetsBasisGuideline": true,
"guidance": "Above roughly $500,000 of depreciable basis a study usually pays for itself, provided the deduction is usable against the owner's passive-activity position this year and the hold period is long enough to outrun recapture. All three conditions, or the honest answer is no."
},
"depreciationByYear": [
{
"year": 2026,
"withoutStudy": 86150,
"conservative": 1395690,
"optimal": 1886768
},
{
"year": 2027,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
},
{
"year": 2028,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
},
{
"year": 2029,
"withoutStudy": 86150,
"conservative": 51690,
"optimal": 38768
}
],
"limitations": [
"This is a planning estimate computed from the facts supplied. No documents were read, so no amount here is traced to an invoice, trial balance or AIA pay application.",
"Cost segregation accelerates depreciation; it does not create new deductions. Over the life of the building the same basis is recovered either way.",
"On a taxable sale at a gain, recapture applies, up to the amount of that gain, however long the property was held, outside the Opportunity Zone 10-year rule (a qualifying investment held 10 years with the IRC §1400Z-2(c) election): §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer.",
"A deduction is only usable against the owner's passive-activity position for that year; a large paper deduction is worth nothing to a taxpayer who cannot use it.",
"This is educational information, not tax advice, and it is not a completed cost segregation study."
],
"opportunityZone": {
"conditions": [
"Recapture is eliminated only after a 10-year hold combined with the §1400Z-2(c) fair-market-value basis election. Before year 10, recapture is entirely normal: §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer.",
"A QOF interest funded with deferred gain starts at a $0 tax basis under §1400Z-2(b)(2)(B), and partnership losses are deductible only up to basis under §704(d) — so accelerated depreciation can be real and still unusable in the year it arises.",
"In practice the deduction is usually still usable, because a partner's share of partnership debt counts as basis under §752 and OZ real estate typically runs 50–70% leverage. Check the specific capital account rather than assuming either way.",
"Selling the QOF interest and the fund selling assets do not behave identically. Do not state one and imply the other.",
"For a substantial improvement, the 30-month test under §1400Z-2 and the 31-month working-capital safe harbour are separate clocks from placed-in-service, and which costs land in which year changes what the study is worth."
],
"furtherReading": "https://www.clickdragfinance.com/opportunity-zone-cost-segregation",
"note": "The depreciation figures above are unchanged by Opportunity Zone status. What changes is which conditions have to travel with them."
},
"nextStep": {
"action": "book_cost_segregation_consult",
"description": "Call book_cost_segregation_consult if the person wants to speak to someone or start a study.",
"url": "https://www.clickdragfinance.com/qualifier"
}
}How to phrase the answer:
The depreciation figures are the same as without the flag, as opportunityZone.note: "The depreciation figures above are unchanged by Opportunity Zone status. What changes is which conditions have to travel with them." The flag adds opportunityZone.conditions. Carry each condition with the claim it limits, in the same sentence, quoted exactly:
opportunityZone.conditions[0]: "Recapture is eliminated only after a 10-year hold combined with the §1400Z-2(c) fair-market-value basis election. Before year 10, recapture is entirely normal: §1245 recapture on the 5- and 7-year property is ordinary income, as is §1250 recapture of the depreciation taken above straight-line (bonus included) on 15-year land improvements held more than one year, and the rest of the depreciation on those land improvements and on the 27.5- or 39-year structure is unrecaptured §1250 gain, taxed at up to 25% for a noncorporate taxpayer."opportunityZone.conditions[1]: "A QOF interest funded with deferred gain starts at a $0 tax basis under §1400Z-2(b)(2)(B), and partnership losses are deductible only up to basis under §704(d) — so accelerated depreciation can be real and still unusable in the year it arises."opportunityZone.conditions[2]: "In practice the deduction is usually still usable, because a partner's share of partnership debt counts as basis under §752 and OZ real estate typically runs 50–70% leverage. Check the specific capital account rather than assuming either way."opportunityZone.conditions[3]: "Selling the QOF interest and the fund selling assets do not behave identically. Do not state one and imply the other."opportunityZone.conditions[4]: "For a substantial improvement, the 30-month test under §1400Z-2 and the 31-month working-capital safe harbour are separate clocks from placed-in-service, and which costs land in which year changes what the study is worth."
Also send bonus.basis and assessment.guidance from the reply, quoted exactly, and relay the fee block as returned: for this input fee.aiReport is null, and fee.aiReportUnavailable says why; send it with the figure and do not drop it.
bonus.basis: "Acquired (or construction begun) on 2026-03-14, after 2025-01-19, so 100% bonus depreciation applies and is permanent under OBBBA. Per IRS Notice 2026-11 the acquired-date test turns on the written binding contract, not the closing date: the acquired date is the latest of the date the contract was signed, the date it became enforceable under state law, the end of any cancellation period, and the date any contingency was satisfied (Treas. Reg. §1.168(k)-2(b)(5)(ii)(B)). This applies to a written binding contract, meaning one enforceable under state law that does not limit damages to a specified amount (for example through a liquidated damages clause); under a contract that is not binding in that sense, the acquired date is generally when the taxpayer has paid or incurred more than 10 percent of the total cost, excluding land and preliminary activities (Treas. Reg. §1.168(k)-2(b)(5)(iii) and (v))."assessment.guidance: "Above roughly $500,000 of depreciable basis a study usually pays for itself, provided the deduction is usable against the owner's passive-activity position this year and the hold period is long enough to outrun recapture. All three conditions, or the honest answer is no."
Say that this is a planning estimate and not a completed study, and that the API cannot order or pay for a study.
For assistants that only read
An assistant that can fetch pages but not call APIs can read these instead. All are generated from the same contract as the API.
- llms.txt: the short, extractable summary of the business and the tools
- llms-full.txt: the long form: every tool, the benchmark table and the pricing, generated from the same code as the API
- developers-compact.md: the compact Markdown: curl examples only, long replies listed by their top-level fields
- developers.md: this documentation as Markdown, with every reply in full
- api-catalog: the RFC 9727 API catalog (linkset) pointing at the OpenAPI file, this documentation and the MCP endpoint
- openapi.json: the OpenAPI 3.1 description, with request and response examples
- mcp.json: the MCP server descriptor
- ai-plugin.json: the ChatGPT plugin-style manifest
- claude-skill.md: the Claude Agent Skill
- chatgpt-instructions.md: instructions for a custom GPT Action
Frequently Asked Questions
What are the cost segregation API rate limits?
60 requests a minute for quote_cost_segregation_study; 120 requests a minute for get_cost_segregation_pricing, get_cost_segregation_benchmarks, get_cost_segregation_provider_facts; 5 requests a minute for book_cost_segregation_consult. The ClickDrag Finance cost segregation API also limits its MCP endpoint to 60 requests a minute in total. Limits are approximate: treat them as a guard, not an exact quota, and back off when you receive a 429 with a Retry-After header.
Is there an OpenAPI spec for the cost segregation API?
Yes. An OpenAPI 3.1 description of the ClickDrag Finance cost segregation API is served at https://www.clickdragfinance.com/openapi.json, generated from the same contract as the MCP server, with request and response examples for every operation. It needs no API key.
What does a validation error from the cost segregation API look like?
The ClickDrag Finance cost segregation API answers HTTP 400 with a JSON body: error is "invalid_request", message is the first problem, fieldErrors lists up to 20 of them, schema carries the tool's full input schema, and documentation links the tool's section of https://www.clickdragfinance.com/developers.md. For example, quote_cost_segregation_study called with only a property type returns this message: Supply a dollar amount: purchasePrice for a purchase, constructionCost for new construction, or renovationCost for a renovation. Every figure in the response scales with it, so it cannot be assumed.
Which MCP protocol versions does the cost segregation MCP server support?
The MCP server of the ClickDrag Finance cost segregation API, at https://www.clickdragfinance.com/api/mcp, speaks MCP protocol versions 2025-11-25, 2025-06-18, 2025-03-26 over Streamable HTTP, newest first. A client that asks for another version is answered with the newest, and a client that sends no MCP-Protocol-Version header is treated as 2025-03-26.
Can a browser call the cost segregation API directly?
Yes. The ClickDrag Finance cost segregation API answers every request with Access-Control-Allow-Origin: * and Access-Control-Allow-Methods: GET, POST, OPTIONS, and OPTIONS preflights return 204. It sends no credentials and accepts none, so cross-origin calls need no key.
Is it safe to retry the cost segregation consult call?
Only after a failure. In the ClickDrag Finance cost segregation API, book_cost_segregation_consult is not idempotent: a retry after a success creates a second consultation request and a second email to our team. HTTP 503 means nothing was recorded, so a retry cannot create a duplicate: wait the Retry-After seconds (5 for a transient failure, 600 when the hourly capacity is full).
Changelog
1.1.0, 2026-10-12. Additive only; no request that worked before stops working.
- HTTP 413 for a POST body over 65,536 bytes, on the REST routes and the MCP endpoint.
- A
documentationfield in every 400 body, linking the tool's section of/developers.md. - A
Linkheader on every reply (service-descto the OpenAPI file,service-docto this documentation), exposed to browsers. - Retry-After is 600 seconds when the consult hourly capacity is full (it stays 5 for a transient failure); a failed body carries
reason:capacityorunrecorded. - Strings containing control characters, or an unpaired UTF-16 surrogate, are refused with a 400 naming the field.
- Over MCP, a validation failure lists every error and the
documentationURL in the tool error text and instructuredContent. - The body size limit is enforced while the body is read: a body with no declared length is cancelled once it passes the limit.
- A validation reply lists at most 20 field errors, then one entry counting the rest;
messageis the first error only. - Request and error examples in the OpenAPI file, and example replies that are the handlers' real output.
- The provider-facts
turnaroundfigures now state their condition (counted from receipt of documents). - Reply wording only, changed in place on 2026-10-12 after
1.1.0was deployed the same day; no field added or removed, so the version stays1.1.0(registry publish pending):fee.fullyEngineeredAudience,fee.aiReportUnavailableand the tiers'appropriateFornow say the study is offered to an owner at or above the report ceiling as well as to a CPA or advisor, and that the report is offered to a CPA or advisor for a client's property under the ceiling as well as to an owner (ordering happens on the website, never through this API). The report's size condition no longer says "you own".
Building something with this?
Tell us what you are building and what is missing: howard@clickdragfinance.com. For the overview written for AI agents, see cost segregation for AI agents.
Not a developer? Start your cost segregation study, see what a cost segregation study costs, or read how Opportunity Zones and cost segregation fit together.
Nothing on this page or returned by these endpoints is tax advice, and no estimate is a completed cost segregation study.