Reference

REST API

Programmatic access to the ClearCost estimate engine and your exclusive leads. Available on the Enterprise plan. Base URL https://getclearcost.com/api/v1.

Authentication

Create a key under Website Embed → API access. Send it as a Bearer token. Keys are shown once at creation; store them securely. Requests are rate limited per account.

Authorization header
Authorization: Bearer cc_live_xxx

POST /v1/estimate

Returns a Fair Market Rate using your per-account price calibration. Does not create a lead.

cURL
curl -X POST https://getclearcost.com/api/v1/estimate \
  -H "Authorization: Bearer cc_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "deck",
    "zipCode": "30080",
    "dimensionsSqft": 320,
    "finishLevel": "standard",
    "features": ["post_cap_lights"],
    "answers": {
      "status": "resurface",
      "railing_material": "composite"
    }
  }'

Response: { estimate: { min_price, max_price, labor_hours, labor_cost, material_cost, confidence }, scope_inclusions: [...] }

The answers object

Optional, and the single biggest lever on accuracy. category, dimensionsSqft and finishLevel describe the size and quality of a job but not its scope — they cannot tell a kitchen whose cabinets are being kept from one being gutted, and those differ by more than 80%. Send answers and you get the price for the job you described; omit it and you get the default full-scope price for that category.

Unknown keys are ignored rather than rejected, so you can pass a superset safely. The same object is accepted by POST /v1/leads and is stored on the lead.

KeyCategoryValues
statusdecknew · replace · resurface
project_typeroofingfull_replacement · repair · new_roof
roof_materialroofingasphalt_3tab · asphalt_architectural · metal · tile · cedar · not_sure
roof_pitchroofingwalkable · moderate · steep
storiesroofing1 · 2 · 3_plus
layersroofingone · two_plus · unsure
repair_extentroofingsmall · section · large
roof_featuresroofingarray: skylight_reseal · chimney_reflash · valley_rework · gutter_replacement · decking_repair
fence_materialfencingchain_link · wood_privacy · vinyl · aluminum · composite · wrought_iron · not_sure
fence_heightfencing4ft · 6ft · 8ft
terrainfencingflat · gentle_slope · steep_rocky
gatesfencingobject: { walk_gates: number, drive_gates: number }
fence_featuresfencingarray: fence_stain · fence_lattice · fence_caps · fence_gate_opener · fence_slats
finishconcrete_masonrybroom · exposed_aggregate · colored · stamped · stamped_colored
thickness_reinforcementconcrete_masonry4in_standard · 4in_mesh · 6in_rebar
site_prepconcrete_masonrynew · replace · over_dirt
concrete_featuresconcrete_masonryarray: concrete_seal · concrete_saw_joints · concrete_thick_edges · concrete_steps · concrete_drainage
railing_materialdeckpine · cedar · composite · aluminum · glass · cable · none
customizationsdeckarray: picture_frame_steps · fascia · skirting · post_cap_lights · riser_lights
project_typekitchen_remodelcosmetic · full_gut
cabinetrykitchen_remodelkeep · reface · stock · custom
bathroom_typebath_remodelpowder · guest · master
wet_areabath_remodelno_change · swap · conversion · relocate
tile_coveragebath_remodelfloor · floor_shower · full_tile
vanitybath_remodelkeep · single · double · floating
flooring_materialflooringluxury_vinyl_plank · hardwood · laminate · tile · carpet
color_changeinterior_painting, exterior_paintingrefresh · drastic_change

POST /v1/leads

Prices the project server-side and creates an exclusive lead (also fires your CRM webhook + email).

cURL
curl -X POST https://getclearcost.com/api/v1/leads \
  -H "Authorization: Bearer cc_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "deck",
    "zipCode": "30080",
    "dimensionsSqft": 320,
    "finishLevel": "standard",
    "features": [],
    "customerName": "Jane Doe",
    "customerEmail": "jane@example.com",
    "customerPhone": "555-123-4567"
  }'

Response: { lead_id, pricing: { minPrice, maxPrice } } (HTTP 201).

GET /v1/leads

Lists your embed leads, newest first. Query params limit (1–100, default 25) and offset (default 0). Returns only the leads captured by your own embed.

Response: { leads: [{ id, category, location_zip, estimated_price_min, estimated_price_max, customer_name, customer_email, customer_phone, status, created_at }], limit, offset, has_more }. Paginate until has_more is false. The response is sent Cache-Control: no-store because it carries customer contact details.

Note on casing. Response fields on /v1/leads are snake_case; the pricing object on the POST response is camelCase (minPrice/maxPrice) for backward compatibility. Estimate responses are snake_case throughout.
Server-to-server only. The API sends no CORS headers, so it can't be called from a browser on another origin — keep your key on your backend. This also means there are no CSRF concerns.

Errors

Errors return { "error": "..." } with a standard status code: 400 (validation or an unoffered/pricing-only project), 401 (bad/missing key), 403 (no embed configured, plan lacks API access, or inactive subscription), 429 (rate limited — see Retry-After), 500 (server error). Successful POST /v1/leads returns 201.