Skip to content

    Jet.Build API Reference

    Authenticate, read project context, and work with daily reports, drawings, inspections, RFIs, submittals and tasks. Every endpoint lists its fields, returned objects and status values.

    Base URLhttps://api.jet.build

    Overview

    The Jet.Build API is organized by module. Start with Login to get a token, use Projects to read the identifiers, groups, time zone and date settings for a project, then call the module endpoints.

    Authentication

    Every request except POST /login needs an API token. Requests run as the token's user, so project visibility and access depend on that user. Use the Token prefix — not Bearer.

    Headers
    Authorization: Token YOUR_API_TOKEN
    Accept: application/json

    Missing or invalid tokens return 401 Unauthorized.

    Request conventions

    Encoding
    GET uses query or path parameters. Writes use form fields (multipart/form-data with files). JSON request bodies are not supported. Let FormData set the Content-Type boundary.
    Dates
    iso2 = US → MM/DD/YYYY. Any other iso2 → DD/MM/YYYY. Unparseable dates silently become the server's current date, so validate first.
    Time zone
    Send an IANA identifier such as America/New_York. Display timestamps like "Wed Oct 28, 2026 at 03:30 PM" carry no offset.
    Repeated fields
    Inspections, Punch Lists, RFIs, Submittals and Tasks take multiple recipients or workflow users by repeating the field name — not commas or JSON. Drawings uploads are the exception and use JSON arrays.
    Presence flags
    is_bid_rfi and wfN_complete are true whenever the field is present, even with value false. Omit them for false.
    Identifiers
    Database ids (pk, project_pk, rfi_pk, task_pk) and UUIDs are separate. Lookups and updates use database ids.

    Integration flow

    1. 1

      POST /login — Read the token from the response.

    2. 2

      GET /projects — Pick a project and keep its pk.

    3. 3

      GET /projects?project_pk=… — Read title, project_uuid, organization_id, groups, timezone and iso2.

    4. 4

      Module endpoints — Pass those values to Daily Reports, Drawings, Inspections, Punch Lists, RFIs, Submittals and Tasks.

    Shared objects

    Structures reused across RFIs, Submittals and Tasks. Linked types throughout this page jump here.

    Due date

    Returned for due_by on RFIs and Tasks. `date` follows the iso2 format (MM/DD/YYYY for US, DD/MM/YYYY otherwise); `display` uses an abbreviated month.

    FieldTypeDescription
    datestringDate in the format selected by iso2.
    displaystringReadable date, e.g. Sep 30, 2026.
    Example
    {
      "date": "09/30/2026",
      "display": "Sep 30, 2026"
    }

    Status

    Computed status returned for RFIs (list and create) and Tasks (list and create). days_overdue = local date minus due date.

    FieldTypeDescription
    statusstringLabel such as OPEN or CLOSED. See status values.
    days_overdueintegerNegative: due in the future. Zero: due today. Positive: past due.
    Example
    {
      "status": "OPEN",
      "days_overdue": -8
    }

    Recipients (ccd)

    Distribution recipients stored on RFIs and Tasks. Built from repeated intended_for and intended_for_groups fields. Separate from workflow participants.

    FieldTypeDescription
    groupsinteger[]Project group pk values.
    usersstring[]Recipient email addresses.
    Example
    {
      "groups": [12, 34],
      "users": ["manager@example.com", "owner@example.com"]
    }

    Workflow step

    RFIs, Submittals and Tasks support up to five workflow steps (wf1–wf5). Trailing empty steps are removed; empty steps before the last populated one are kept. Updates replace the whole workflow.

    FieldTypeDescription
    groupsinteger[]Group pk values from wfN_groups.
    usersstring[]Emails from wfN_emails.
    completebooleanTrue when wfN_complete is present in the request (any value, even false).
    Example
    [
      { "groups": [12], "users": ["architect@example.com"], "complete": true },
      { "groups": [], "users": ["owner@example.com"], "complete": false }
    ]

    Ball in Court

    Derived from the workflow. Returned as bic in list responses and ball_in_court in create responses. The selection algorithm and empty value are pending confirmation.

    FieldTypeDescription
    groupsinteger[]Groups currently responsible.
    usersstring[]Users currently responsible.
    Example
    {
      "groups": [12],
      "users": ["architect@example.com"]
    }

    Attachment

    Stored attachment on RFIs and Tasks. `file` is a relative storage path, not a public download URL. Updates append files; .heic files are renamed .jpg.

    FieldTypeDescription
    filestringRelative storage path.
    filenamestringStored filename after character substitutions.
    uploaded_onstringLocal display timestamp, no time zone offset.
    Example
    {
      "file": "10/projects/123/RFIs/1793215800/detail.pdf",
      "filename": "detail.pdf",
      "uploaded_on": "Wed Oct 28, 2026 at 03:30 PM"
    }

    Module

    Login

    Authenticate with an email and password to retrieve the user's existing API token, then send it as `Authorization: Token …` on every other request.

    Log in and retrieve token

    POST/login

    Submit credentials as form fields. JSON request bodies are not supported. Returns the user's existing token; it does not create, rotate or refresh tokens.

    Encoding: application/x-www-form-urlencoded

    Form fields

    FieldTypeDescription
    emailRequiredstringUser's email address. Case-sensitive field name.
    passwordRequiredstringUser's password.
    curl --request POST "https://api.jet.build/login" \
      -H "Accept: application/json" \
      --data-urlencode "email=user@example.com" \
      --data-urlencode "password=YOUR_PASSWORD"

    Response

    200 OK

    Response
    {
      "email": "user@example.com",
      "display_name": "Example User",
      "user_name": "Example User",
      "token": "YOUR_API_TOKEN"
    }

    Login objects

    Login response

    Returned by a successful login.

    FieldTypeDescription
    emailstringAuthenticated user's email.
    display_namestringFrom the user's display-name method.
    user_namestringFrom the user's full-name method. May differ from display_name.
    tokenstringExisting API token for the user.
    Example
    {
      "email": "user@example.com",
      "display_name": "Example User",
      "user_name": "Example User",
      "token": "YOUR_API_TOKEN"
    }

    Login errors

    400 Bad Request
    email or password field missing. Body is null.
    401 Unauthorized
    Invalid credentials. Body is null, no reason given.
    Other
    A missing token record is not handled locally; status depends on global error handling.

    Pending confirmation: Token expiration, rotation and revocation; Rate limits and account lockout; MFA / SSO accounts and password login; CORS settings for browser integrations.

    Module

    Projects

    List the projects available to the token's user and retrieve project details: identifiers, groups, users, module access, time zone and date settings used by every other module.

    List available projects

    GET/projects

    Returns organization projects and external assignments. No pagination, search or filtering. A project can appear in both arrays — deduplicate by pk.

    curl --get "https://api.jet.build/projects" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json"

    Response

    200 OK

    • Returns ProjectSummary[] — Projects in the user's organization, status act or pip, user in users_list.
    • Returns ProjectSummary[] — Projects linked through Person_Info records. No status or organization filter.
    Response
    {
      "org_projects": [
        { "pk": 123, "title": "Example Office Project", "status": "<status label>" }
      ],
      "ext_projects": [
        { "pk": 456, "title": "Example Residential Project", "status": "<status label>" }
      ]
    }

    Retrieve project details

    GET/projects?project_pk={project_pk}

    Including project_pk selects the detail operation. The response does not include pk — keep the value you sent.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier (pk from the list).
    cURL
    curl --get "https://api.jet.build/projects" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123"

    Response

    200 OK

    Projects objects

    Project summary

    Item in org_projects and ext_projects.

    FieldTypeDescription
    pkintegerProject database primary key. Called project_pk or project_id elsewhere.
    titlestringProject name.
    statusstringHuman-readable status label.
    Example
    { "pk": 123, "title": "Example Office Project", "status": "<status label>" }

    Project detail

    Returned by GET /projects?project_pk=…

    FieldTypeDescription
    titlestringProject name. Use as project_name in write requests.
    project_uuidstring (UUID)Separate from pk. Never send as project_pk.
    access_typeenumadmin, coordinator or external.
    organization_idintegerUse where an endpoint requires organization_id.
    companiesanyStored company data. Schema pending confirmation.
    groupsGroup[]Project groups.
    usersstring[]users_list emails plus Person_Info user_id values. Not deduplicated.
    user_appsUserAppsModule access settings.
    timezonestringe.g. America/New_York.
    iso2stringCountry code, e.g. US. Controls date format.
    workflowsanyAdmin only. Schema pending confirmation.
    Example
    {
      "title": "Example Project",
      "project_uuid": "11111111-1111-4111-8111-111111111111",
      "access_type": "admin",
      "organization_id": 10,
      "companies": "…",
      "groups": [{ "pk": 12, "title": "Design Team", "members": "…" }],
      "users": ["manager@example.com"],
      "user_apps": { "RFIs": true, "Tasks": true, "…": true },
      "timezone": "America/New_York",
      "iso2": "US",
      "workflows": "…"
    }

    Group

    Use group pk values for intended_for_groups and wfN_groups. Never substitute names.

    FieldTypeDescription
    pkintegerGroup database identifier.
    titlestringGroup name.
    membersanyStored membership. Structure pending confirmation.
    Example
    { "pk": 12, "title": "Design Team", "members": "…" }

    User apps

    Exact, case-sensitive keys. Admins receive all true; coordinators and external users get values from their Person_Info record. Not a full per-action permission contract.

    FieldTypeDescription
    Daily ReportsbooleanPerson_Info: reports
    DrawingsbooleanPerson_Info: drawings
    DisciplinesbooleanPerson_Info: drawings (same setting)
    FilesbooleanPerson_Info: files
    ObservationsbooleanPerson_Info: observations
    Punch ListsbooleanPerson_Info: punches
    RFIsbooleanPerson_Info: rfis
    SubmittalsbooleanPerson_Info: submittals
    TasksbooleanPerson_Info: tasks
    Example
    {
      "Daily Reports": true, "Drawings": true, "Disciplines": true,
      "Files": true, "Observations": true, "Punch Lists": true,
      "RFIs": true, "Submittals": true, "Tasks": true
    }

    Projects status values

    access_type

    Evaluated in this order for project details.

    admin
    User's email is in the project's users_list. Receives workflows.
    coordinator
    Linked through Person_Info with ext_admin = true.
    external
    Linked through Person_Info with ext_admin = false.
    401
    No matching record — request is rejected.

    Stored project status

    Used to filter org_projects. Display labels are pending confirmation.

    act
    Included in org_projects.
    pip
    Included in org_projects.

    Projects errors

    401 Unauthorized
    Unauthenticated, or user has no access to the project. Body is null.
    Other
    Unknown or invalid project_pk is not handled locally; do not assume 404.

    Module

    Daily Reports

    List, create, read and finalize daily reports and contractor subreports, and add, move or remove workforce, inspections, equipment, deliveries, miscellaneous, safety and quantity entries, plus report files and photos.

    List project reports

    GET/reports

    Returns every report for a project, newest date first, with main reports before subreports for the same date.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier.
    iso2RequiredstringDate-format selector. Only uppercase US gives MM/DD/YYYY; anything else gives DD/MM/YYYY.
    cURL
    curl --get "https://api.jet.build/reports" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123" \
      --data-urlencode "iso2=US"

    Response

    200 OK — array (empty result returns [])

    • Returns integer — Report database identifier. Use for detail paths and section changes.
    • Returns UUID — Report UUID, separate from pk.
    • Returns string | null — Contractor name for subreports.
    • Returns boolean — True for contractor subreports.
    • Returns object — Formatted report date.
    • Returns boolean — Whether the report is finalized.
    • Returns string — Finalization display date.
    • Returns string — Finalizing user's name and email.
    • Returns WorkflowStep[] — Workflow steps.
    • Returns object | null — Ball in Court when not final; null when final.
    • Returns object — Recipients.

    Create a report or subreport

    POST/reports

    Creates a main report, or a contractor subreport when contractor is present. Some data is copied from the latest previous report.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier.
    iso2RequiredstringDate-format selector.
    report_dateRequireddate stringDate in the iso2 format. An unparseable date silently becomes the server's current date.

    Optional form fields

    FieldTypeDescription
    contractorstring (max 360)Its presence, even empty, creates a subreport. Omit for a main report.
    parent_report_pkintegerParent report for a subreport. Otherwise a same-project, same-date main report is searched for.
    copy_notespresence flagKeeps copied workforce, equipment and miscellaneous notes. copy_notes=false still counts.
    curl --request POST "https://api.jet.build/reports" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "project_pk=123" \
      --form-string "iso2=US" \
      --form-string "report_date=11/09/2026"

    Response

    200 OK — one report list object

    Retrieve report details

    GET/reports/details/<report_pk>

    Returns the full report, including every section, files, photos and weather.

    Query parameters

    FieldTypeDescription
    iso2RequiredstringDate-format selector.
    cURL
    curl --get "https://api.jet.build/reports/details/456" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    • Returns mixed — As in the report list.
    • Returns string — Finalization attribution.
    • Returns array — Workforce entries.
    • Returns array — Section entries.
    • Returns array — Quantity line items.
    • Returns array — Each includes a generated document_url.
    • Returns object — Stored weather.

    Finalize a report

    POST/reports/details/<report_pk>

    Marks the report final with the signed-in user's attribution and emails the project's report distribution list.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    timezoneRequiredstringValid time zone identifier, e.g. America/New_York.
    iso2RequiredstringDate-format selector.
    cURL
    curl --request POST "https://api.jet.build/reports/details/456" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "timezone=America/New_York" \
      --form-string "iso2=US"

    Response

    200 OK — response data is null

    Add a workforce entry

    POST/reports/workforce

    Inserts a workforce entry at a position. PUT updates an entry; DELETE removes one.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    report_pkRequiredintegerReport database identifier.
    positionRequiredintegerOne-based insertion position (1 to N+1).
    company_nameRequiredstringStored as company.
    workersRequiredintegerCommas removed; unparseable becomes 0.
    hours, ot_hours, ot_rateRequirednumberCommas removed; unparseable becomes 0.
    notesRequiredstringEntry notes.

    PUT adds

    FieldTypeDescription
    current_positionRequiredintegerExisting entry to replace; position is its destination.
    curl --request POST "https://api.jet.build/reports/workforce" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "report_pk=456" \
      --form-string "position=1" \
      --form-string "company_name=Example Contractor" \
      --form-string "workers=8" \
      --form-string "hours=8" \
      --form-string "ot_hours=0" \
      --form-string "ot_rate=1.5" \
      --form-string "notes=Installed framing on level 2."

    Response

    200 OK — POST returns the new entry; PUT returns the full workforce array; DELETE returns null

    Response
    {
      "position": 1,
      "company": "Example Contractor",
      "workers": 8,
      "hours": 8.0,
      "ot_rate": 1.5,
      "ot_hours": 0.0,
      "notes": "Installed framing on level 2."
    }

    Add other section entries

    POST/reports/inspections · equipments · deliveries · others · safety

    Same pattern for inspections, equipment, deliveries, miscellaneous and safety: POST inserts, PUT (with current_position) replaces and moves, DELETE removes by position.

    Encoding: multipart/form-data (DELETE reads request.data)

    Every section

    FieldTypeDescription
    report_pkRequiredintegerReport database identifier.
    positionRequiredintegerOne-based position.
    current_positionConditionalintegerPUT only — the existing entry.

    /reports/inspections

    FieldTypeDescription
    inspectionRequiredstringStored as title.
    inspection_byRequiredstringStored as by.
    inspection_timeRequiredhh:mm AM/PMStored as time; unparseable becomes null.
    notesRequiredstringNotes.

    /reports/equipments

    FieldTypeDescription
    equipment_nameRequiredstringStored as title.
    operating_hoursRequirednumberStored as hours; unparseable becomes 0.
    inspection_timeRequiredhh:mm AM/PMStored as time; unparseable becomes null.
    notesRequiredstringNotes. Entries appear under equipment in details.

    /reports/deliveries

    FieldTypeDescription
    delivery_fromRequiredstringStored as from.
    delivery_timeRequiredhh:mm AM/PMStored as time.
    contentsRequiredstringDelivery contents.

    /reports/others

    FieldTypeDescription
    title, notesRequiredstringEntries appear under miscellaneous in details.

    /reports/safety

    FieldTypeDescription
    titleRequiredstringOccurrence title.
    occurrence_timeRequiredhh:mm AM/PMStored as time.
    notesRequiredstringNotes. by is set to the signed-in user's email; incident_id starts null.
    linked_incident_idintegerPUT only. Omitted or invalid sets incident_id to null. Existence not validated.
    curl --request POST "https://api.jet.build/reports/inspections" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "report_pk=456" \
      --form-string "position=1" \
      --form-string "inspection=Framing inspection" \
      --form-string "inspection_by=City inspector" \
      --form-string "inspection_time=02:30 PM" \
      --form-string "notes=Passed."

    Response

    200 OK — inspection POST returns the new entry; all other operations return null

    Upload a report file

    POST/reports/files

    Uploads one file to a report at a position.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    report_pk, project_pk, organization_idRequiredintegerReport, project and organization identifiers.
    positionRequiredintegerOne-based position.
    titleRequiredstringFile title.
    filenameRequiredfileOne binary file per request; only the first is recorded.
    cURL
    curl --request POST "https://api.jet.build/reports/files" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "report_pk=456" \
      --form-string "project_pk=123" \
      --form-string "organization_id=10" \
      --form-string "position=1" \
      --form-string "title=Delivery Ticket" \
      --form "filename=@./delivery-ticket.pdf"

    Response

    200 OK — the file entry (304 with null data when no file is uploaded)

    Response
    {
      "position": 1,
      "title": "Delivery Ticket",
      "file": "10/projects/123/reports/456/files/delivery-ticket.pdf",
      "filename": "delivery-ticket.pdf"
    }

    Upload photos

    POST/reports/photos

    Appends one or more photos to a report. Repeat filename for each photo.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    organization_id, project_pk, report_pkRequiredintegerOrganization, project and report identifiers.
    filenameRequiredfile (repeat)Photo file. Repeat for multiple photos.

    Optional form fields

    FieldTypeDescription
    location, notesstringApplied to every photo in the upload. Default empty string.
    photo_timehh AM/PMFallback when no EXIF time is found. Not parsed during upload.
    cURL
    curl --request POST "https://api.jet.build/reports/photos" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "organization_id=10" \
      --form-string "project_pk=123" \
      --form-string "report_pk=456" \
      --form-string "location=Level 2" \
      --form-string "notes=Framing progress." \
      --form-string "photo_time=02:30 PM" \
      --form "filename=@./photo-1.jpg" \
      --form "filename=@./photo-2.jpg"

    Response

    200 OK — empty string

    Update photo details

    PUT/reports/photos

    Updates time, location and notes on the first photo with an exact filename match. The image itself is not replaced.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    report_pkRequiredintegerReport database identifier.
    filenameRequiredstringStored filename to match.
    photo_timeRequiredhh:mm AM/PMUnparseable becomes null.
    location, notesRequiredstringReplacement values.
    cURL
    curl --request PUT "https://api.jet.build/reports/photos" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "report_pk=456" \
      --form-string "filename=photo-1.jpg" \
      --form-string "photo_time=02:30 PM" \
      --form-string "location=Level 2" \
      --form-string "notes=Framing complete."

    Response

    200 OK — response data is null, even when no photo matches

    Add a quantity

    POST/reports/quantities

    Adds a line-item quantity to a report. Progress is based on today's amount only.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    report_pkRequiredintegerReport database identifier.
    positionRequiredintegerOne-based position.
    today, line_item_totalRequirednumberRounded to 2 decimals. No thousands separators. Total must be positive.
    line_item_idRequiredintegerStored as pk.
    line_item_title, line_item_unitsRequiredstringStored as title and units.
    cURL
    curl --request POST "https://api.jet.build/reports/quantities" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "report_pk=456" \
      --form-string "position=1" \
      --form-string "today=25.5" \
      --form-string "line_item_total=400" \
      --form-string "line_item_id=88" \
      --form-string "line_item_title=Concrete slab" \
      --form-string "line_item_units=CY"

    Response

    200 OK — response data is null

    Update a quantity

    PUT/reports/quantities

    Updates today's amount and recalculates the running total from earlier reports. Reads request.data (JSON).

    Encoding: application/json

    Body fields

    FieldTypeDescription
    report_pkRequiredintegerReport database identifier.
    current_position, positionRequiredintegerExisting entry and destination.
    todayRequirednumberToday's quantity.
    curl --request PUT "https://api.jet.build/reports/quantities" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      -H "Content-Type: application/json" \
      --data '{"report_pk":456,"current_position":1,"position":1,"today":25.5}'

    Response

    200 OK — PUT returns the full quantities array; DELETE returns 200

    Daily Reports objects

    Report date

    date follows iso2 (MM/DD/YYYY for US, otherwise DD/MM/YYYY); display uses abbreviated month, day and year.

    FieldTypeDescription
    datestringFormatted date.
    displaystringReadable date.
    Example
    { "date": "11/09/2026", "display": "Nov 09, 2026" }

    Workforce entry

    One company's crew on the report.

    FieldTypeDescription
    positionintegerOne-based position.
    companystringCompany name.
    workersintegerWorker count.
    hours, ot_rate, ot_hoursnumberHours and overtime.
    notesstring | nullNotes.
    Example
    { "position": 1, "company": "Example Contractor", "workers": 8, "hours": 8.0, "ot_rate": 1.5, "ot_hours": 0.0, "notes": null }

    Section entries

    Stored keys for inspections, equipment, deliveries, miscellaneous and safety. All include position.

    FieldTypeDescription
    inspectionstitle, by, time, notesinspection_id may be absent.
    equipmenttitle, hours, time, notesFrom /reports/equipments.
    deliveriesfrom, time, contentsFrom /reports/deliveries.
    miscellaneoustitle, notesFrom /reports/others.
    safetytitle, by, time, notes, incident_idby is the last editor's email.
    Example
    { "position": 1, "title": "Framing inspection", "by": "City inspector", "time": "02:30 PM", "notes": "Passed." }

    Quantity

    A line-item quantity with running total.

    FieldTypeDescription
    pkintegerLine item identifier.
    positionintegerOne-based position.
    title, unitsstringLine item title and units.
    today, to_date, totalnumberToday's, cumulative and total quantity.
    progressnumberPercent, 2 decimals.
    Example
    { "pk": 88, "position": 1, "title": "Concrete slab", "units": "CY", "today": 25.5, "to_date": 125.5, "total": 400.0, "progress": 31.38 }

    Photo

    Stored photo; report details add a document_url presigned link (30 minutes). Files use position, title, file and filename.

    FieldTypeDescription
    filestringStorage path.
    filenamestringStored filename.
    location, notesstringPhoto details.
    timestring | nullhh AM/PM from EXIF or photo_time.
    document_urlstringDetails only. Use directly; refresh when expired.
    Example
    {
      "file": "10/projects/123/reports/456/photo-1.jpg",
      "filename": "photo-1.jpg",
      "location": "Level 2",
      "time": "02:30 PM",
      "notes": "Framing progress."
    }

    Weather

    Morning, noon and evening observations plus units. Initial values and units come from default_weather (pending confirmation). No weather update endpoint.

    FieldTypeDescription
    morning, noon, eveningobjectEach has time (string), temp, prec, wind (numbers) and icon (string).
    unitsobjectUnits definition — do not assume units.
    Example
    { "morning": { "time": "...", "temp": 0, "prec": 0, "wind": 0, "icon": "..." }, "noon": { ... }, "evening": { ... }, "units": { ... } }

    Daily Reports status values

    Section positions

    Positions are one-based and renumbered from 1 after every change. Ranges are not validated.

    POST position
    Insertion position, 1 to N+1.
    PUT current_position
    Existing entry, 1 to N.
    PUT position
    Destination after the entry is removed, 1 to N.
    DELETE position
    Entry to remove, 1 to N. Refresh details first — positions shift.

    Request body format

    Form fields
    Report creation, finalization, all section POST/PUT, files, photos and quantity POST.
    request.data (JSON)
    All section DELETEs and quantity PUT. Verify deployed parser configuration.
    Times
    hh:mm AM/PM, e.g. 02:30 PM. Unparseable becomes null.

    Daily Reports errors

    401 Unauthorized
    Missing or invalid token. Response data is null.
    304 Not Modified
    File upload with no file.
    400 Bad Request
    Photo DELETE (not implemented).
    Other
    Unknown ids, missing fields, invalid positions or quantities, division by zero and storage failures are handled by global exception handling.
    Silent fallbacks
    Invalid numbers become 0, invalid times and incident ids become null, unmatched photo updates and empty photo uploads still return 200.
    Retries
    No idempotency or locking. Repeats can duplicate reports, entries, files or photos, resend finalization emails, or delete a different entry. Read details before retrying.
    Partial completion
    Reports save before background work finishes; files may upload before the report saves. updated_at is not reliable for sync.

    Pending confirmation: Canonical root URL: /reports or /reports/; Deployed multipart PUT and JSON parser configuration; Global permission and error handling; Request, file-size and photo-format limits; default_weather and weather units; Undocumented routes: /reports/correspondences, /reports/download-photos/<project_pk>, /reports/download-reports/<project_pk>; Line-item lookup endpoint and quantity business rules; Parent workforce duplication during subreport creation; Daily Report Ball-in-Court email preference selection; Any intended restriction on editing finalized reports.

    Module

    Drawings

    Drawings are organized into disciplines; each discipline holds sheets, and each sheet holds versions. Uploading a PDF maps each page to a sheet number and processes asynchronously.

    List project disciplines

    GET/drawings/disciplines/{project_pk}

    Ordered by title ascending. An empty array does not prove the project exists.

    Path parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier.
    cURL
    curl --get "https://api.jet.build/drawings/disciplines/123" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json"

    Response

    200 OK

    Response
    [
      { "pk": 45, "title": "Architectural", "uuid": "11111111-1111-4111-8111-111111111111" },
      { "pk": 46, "title": "Structural", "uuid": "22222222-2222-4222-8222-222222222222" }
    ]

    Current sheets for a discipline

    GET/drawings/disciplines/latest/{discipline_pk}

    Returns the discipline's current sheets. Item schema, ordering and version rules are pending confirmation.

    Path parameters

    FieldTypeDescription
    discipline_pkRequiredintegerDiscipline database identifier.
    cURL
    curl --get "https://api.jet.build/drawings/disciplines/latest/45" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json"

    Response

    200 OK · 404 if discipline not found

    Sheet titles for a discipline

    GET/drawings/sheets/{discipline_pk}

    Returns titles only — no numbers or versions. Do not use it to find sheet numbers for revision uploads.

    Path parameters

    FieldTypeDescription
    discipline_pkRequiredintegerDiscipline database identifier.
    cURL
    curl --get "https://api.jet.build/drawings/sheets/45" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json"

    Response

    200 OK

    Response
    ["Ground Floor Plan", "Second Floor Plan", ""]

    Upload sheets or revisions

    PUT/drawings/sheets/{discipline_pk}

    Upload one PDF. Page N maps to updated_sheets[N]. Existing sheet numbers get a new version; new numbers create sheets. Processing runs in the background.

    Encoding: multipart/form-data

    Path parameters

    FieldTypeDescription
    discipline_pkRequiredintegerTarget discipline.

    Form fields

    FieldTypeDescription
    filenameRequiredfile (PDF)One PDF per request.
    updated_sheetsRequiredJSON string[]Sheet numbers in page order, e.g. ["A-101","A-102"]. Length must equal page count. Case-sensitive.
    drawing_set_idRequiredstringNA, an existing set id, or a new set title.
    organization_idRequiredintegerUsed for storage paths.
    project_pkRequiredintegerProject database identifier.
    intended_for_groupsRequiredJSON integer[]Recipient group ids as a JSON array. Send [] for none.
    intended_forRequiredJSON string[]Recipient emails as a JSON array. Send [] for none.
    cURL
    curl --request PUT "https://api.jet.build/drawings/sheets/45" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form "filename=@./architectural-revisions.pdf" \
      --form-string 'updated_sheets=["A-101","A-102","A-103"]' \
      --form-string "drawing_set_id=NA" \
      --form-string "organization_id=10" \
      --form-string "project_pk=123" \
      --form-string 'intended_for_groups=[12,34]' \
      --form-string 'intended_for=["manager@example.com"]'

    Response

    200 OK — body "200" (job queued)

    Current sheets across a project

    GET/drawings/get-sheets/{project_pk}

    Flat array of current sheets across all disciplines. Use these values to build an RFI linked_sheet reference.

    Path parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier.
    cURL
    curl --get "https://api.jet.build/drawings/get-sheets/123" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json"

    Response

    200 OK

    Response
    [
      {
        "discipline": 45,
        "number": "A-101",
        "title": "Ground Floor Plan",
        "version": 0,
        "file": "10/projects/123/drawings/45/A-101/0"
      }
    ]

    Drawings objects

    Discipline

    Returned by the disciplines list.

    FieldTypeDescription
    pkintegerDiscipline database identifier (discipline_pk).
    titlestringDiscipline name.
    uuidstring (UUID)Separate from pk. Do not use in paths.
    Example
    { "pk": 45, "title": "Architectural", "uuid": "11111111-1111-4111-8111-111111111111" }

    Current sheet

    Item returned by /drawings/get-sheets/{project_pk}.

    FieldTypeDescription
    disciplineintegerDiscipline pk.
    numberstringSheet number, e.g. A-101.
    titlestringSheet title.
    versionintegerCurrent version.
    filestringStorage reference, not a public URL.
    Example
    { "discipline": 45, "number": "A-101", "title": "Ground Floor Plan", "version": 0, "file": "10/projects/123/drawings/45/A-101/0" }

    Stored sheet

    Structure the upload worker stores. Not every GET returns the full object.

    FieldTypeDescription
    numberstringSheet number.
    positionintegerOne-based position in the discipline.
    titlestringEmpty for new sheets.
    obsoletebooleanFalse for new sheets.
    versionsSheetVersion[]Version records.
    sketchesarrayEmpty for new sheets.
    Example
    {
      "number": "A-101",
      "position": 1,
      "title": "",
      "obsolete": false,
      "versions": [
        { "number": 0, "set": null, "file": "10/projects/123/drawings/45/A-101/0", "annots": [] }
      ],
      "sketches": []
    }

    Sheet version

    New sheets start at version 0; revisions append the next number.

    FieldTypeDescription
    numberintegerAssigned by the worker. Do not submit.
    setinteger | nullDrawing set id, or null.
    filestringRelative storage path, no .pdf extension.
    annotsarrayEmpty for new versions.
    Example
    { "number": 0, "set": null, "file": "10/projects/123/drawings/45/A-101/0", "annots": [] }

    Drawings status values

    drawing_set_id values

    NA
    No drawing set. New versions get set: null.
    87 (integer)
    Assign to existing set 87. Not verified by the view.
    Any text
    Creates a new set with that title. Repeating a title creates another set.

    Upload responses

    200 "200"
    Upload accepted and background job queued.
    304
    PDF page count differs from updated_sheets length. Nothing processed.

    Drawings errors

    401 Unauthorized
    Missing or invalid token. Body is null.
    404 Not Found
    Unknown discipline on the latest-sheets endpoint only.
    Other
    Missing fields, bad JSON or invalid PDFs are not handled locally.

    Pending confirmation: Routes /drawings/copy-discipline, /drawings/sets/{project_pk} and /drawings/sketches/ are registered but not yet documented..

    Module

    Files

    Retrieve a project's top-level folders, browse a folder's subfolders, files and links, create folders, upload files (with or without email distribution) and create live links. Folder hierarchy paths and stored file paths are separate values. These routes do not end with trailing slashes.

    Retrieve top-level folders

    GET/files/folders/0

    Lists folders with no parent for the project. The path value 0 represents the project folder root; it is not an actual folder record. Root-level files and links are not returned by this operation.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier.
    cURL
    curl --get "https://api.jet.build/files/folders/0" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123"

    Response

    200 OK — folders; files, links and path are null

    Response
    {
      "folders": [
        {
          "pk": 45,
          "folder_name": "Contracts"
        }
      ],
      "files": null,
      "links": null,
      "path": null
    }

    Browse a folder

    GET/files/folders/{folder_id}

    Returns a folder's immediate child folders, the files and live links directly in it, and its hierarchy path. Use a nonzero folder database primary key.

    Query parameters

    FieldTypeDescription
    organization_idRequiredintegerOrganization identifier used by the folder access check and storage path; supply the project's actual organization identifier.
    cURL
    curl --get "https://api.jet.build/files/folders/45" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "organization_id=10"

    Response

    200 OK — folders, files, links and path

    • Returns array — Immediate child folders, each containing pk and folder_name.
    • Returns File record[] — Serialized files directly in this folder.
    • Returns Live link[] — Serialized live links directly in this folder.
    • Returns string — Folder hierarchy path ending in a slash, e.g. "Contracts/Subcontracts/".

    Create a folder

    POST/files/folders/{folder_id}

    Creates a folder. Use folder_id = 0 for a top-level folder, or an existing folder's database primary key to create a child.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    folder_nameRequiredstringRequested name; model maximum 150 characters.
    project_pkRequiredintegerProject database identifier.

    Optional form field

    FieldTypeDescription
    is_publicpresence flagInclude (e.g. is_public=1) to set true; omit for false. Submitting is_public=false still sets true because the view checks presence.
    cURL
    curl --request POST "https://api.jet.build/files/folders/0" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "folder_name=Contract Documents" \
      --form-string "project_pk=123"

    Response

    200 OK — pk, folder_name and folder_id

    Response
    {
      "pk": 45,
      "folder_name": "Contract_Documents",
      "folder_id": "11111111-1111-4111-8111-111111111111"
    }

    Upload files and return records

    POST/files/files

    Creates file records and returns their serialized details. No email distribution is queued by this POST branch.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    organization_idRequiredintegerOrganization identifier used by the folder access check and storage path; supply the project's actual organization identifier.
    project_pkRequiredintegerProject database identifier.
    folder_idRequiredintegerTarget folder database primary key. The folder foreign key is required; do not use folder_id=0 for file uploads.
    file_pathRequiredstringRelative storage directory suffix. Use the path returned by folder browsing, including its trailing slash, e.g. Contracts/Subcontracts/.
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for upload display timestamps.
    filenameRequiredfileBinary file; repeat the filename field for multiple files.
    cURL
    curl --request POST "https://api.jet.build/files/files" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "organization_id=10" \
      --form-string "project_pk=123" \
      --form-string "folder_id=45" \
      --form-string "file_path=Contracts/" \
      --form-string "timezone=America/New_York" \
      --form "filename=@./agreement.pdf" \
      --form "filename=@./schedule.xlsx"

    Response

    200 OK — array of serialized file records

    • Returns File record[] — One serialized record per uploaded file.

    Upload files with email distribution

    PUT/files/files

    Creates new file records and queues a new-files email. This operation does not edit or replace an existing file record.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    organization_idRequiredintegerOrganization identifier used by the folder access check and storage path; supply the project's actual organization identifier.
    project_idRequiredintegerNote the difference from POST, which uses project_pk.
    folder_idRequiredintegerTarget folder database primary key. The folder foreign key is required; do not use folder_id=0 for file uploads.
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for upload display timestamps.
    project_nameRequiredstringUsed in the distribution email.
    add_textRequiredstringAdditional distributor text; submit an empty string if none.
    filename0, filename1, …RequiredfileBinary files under distinct field names beginning with filename.

    Optional recipient fields

    FieldTypeDescription
    intended_forrepeated stringRecipient email; repeat the field for multiple recipients.
    intended_for_groupsrepeated integerRecipient group identifier, convertible to an integer; repeat for multiple groups.
    cURL
    curl --request PUT "https://api.jet.build/files/files" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "organization_id=10" \
      --form-string "project_id=123" \
      --form-string "folder_id=45" \
      --form-string "timezone=America/New_York" \
      --form-string "project_name=Example Project" \
      --form-string "add_text=Please review the attached documents." \
      --form-string "intended_for=manager@example.com" \
      --form-string "intended_for_groups=12" \
      --form "filename0=@./agreement.pdf" \
      --form "filename1=@./schedule.xlsx"

    Response

    200 OK — response data is null

    Files objects

    File record

    Returned by folder browsing and POST upload. The serialized response does not include raw byte size, folder_id, project_id or uploaded_on.

    FieldTypeDescription
    pkintegerFile database identifier.
    uploaded_on_localstringLocal display timestamp.
    distributionsarrayStored distribution history; the model defaults to an empty array and its item schema was not supplied. Do not infer that the email upload operation adds records to this history.
    object_details.file_pathstringStorage reference, e.g. 10/projects/123/files/Contracts/Subcontracts/agreement.pdf. Not a public URL.
    object_details.document_urlstringGenerated presigned S3 GET URL with a default requested lifetime of 900 seconds (15 minutes). Retrieve folder contents again to generate a fresh URL; use the returned URL directly and do not prepend the API base URL to file_path.
    object_details.file_namestringBasename of the stored file path.
    object_details.is_officebooleanTrue only for .docx, .xlsx and .pptx, case-insensitively. Other formats, including .doc, .xls and .ppt, are not marked as Office files.
    object_details.is_imagebooleanTrue only for .jpg, .jpeg and .png. Other image formats are not marked as images.
    object_details.sizeFile sizeConverted display size and numeric amount.
    Example
    {
      "pk": 789,
      "uploaded_on_local": "Mon Nov 09, 2026 at 03:30 PM",
      "distributions": [],
      "object_details": {
        "file_path": "10/projects/123/files/Contracts/agreement.pdf",
        "document_url": "<generated download URL>",
        "file_name": "agreement.pdf",
        "is_office": false,
        "is_image": false,
        "size": {
          "display": "250.00KB",
          "amount": 250
        }
      }
    }

    File size

    Raw stored size is the storage object's ContentLength in bytes. The serializer returns a converted size object.

    FieldTypeDescription
    displaystringRounded to two decimal places and includes its unit.
    amountnumberConverted numeric value; not explicitly rounded and not a byte count.
    Example
    {
      "display": "1.25MB",
      "amount": 1.25
    }

    Files status values

    Identifiers and paths

    Database primary keys, UUIDs and storage paths are separate values.

    project_pk / project_id
    Project database primary key; POST uploads use project_pk, PUT uploads use project_id.
    folder_id (paths and form fields)
    Numeric folder database primary key, returned as pk. The folder creation response also returns a UUID-valued folder_id; never submit the UUID where a numeric id is expected.
    0 (root sentinel)
    Represents the project folder root for listing and creating top-level folders. Not an actual folder record; do not use it for file uploads.
    Folder path vs stored file path
    Browsing returns a relative hierarchy path with a trailing slash ("Contracts/Subcontracts/"); file records return a storage reference such as 10/projects/123/files/Contracts/Subcontracts/agreement.pdf.

    File size format

    Units use decimal conversions: 1 KB = 1,000 bytes; 1 MB = 1,000,000 bytes; 1 GB = 1,000,000,000 bytes; 1 TB = 1,000,000,000,000 bytes.

    Unit change
    The helper changes units only when the lower-unit amount is greater than 1,000, so an exact boundary remains in the lower unit: 1,000,000 bytes → 1,000.00KB.
    display
    Rounded to two decimal places and includes its unit.
    amount
    Converted numeric value, not explicitly rounded. There is no separate unit property; do not treat amount as a byte count.

    Two upload formats

    POST and PUT use different upload helpers and different file field names; follow the format documented for each operation.

    POST /files/files
    Repeated fields named filename; storage path uses the hierarchy-based file_path.
    PUT /files/files
    Distinct fields beginning with filename (filename0, filename1, …); storage path uses the numeric folder_id and queues email distribution.

    Files errors

    401 Unauthorized
    Unauthenticated requests; the view sets response data to null. The is_public folder flag does not remove the authentication requirement.
    403 Forbidden
    Failed folder browsing access check; response data is null.
    404 Not Found
    Unknown nonzero folder identifier during browsing; response data is null.
    400 Bad Request
    Unimplemented branches: DELETE /files/folders/<folder_id>, PUT /files/folders/<folder_id>, DELETE /files/files and DELETE /files/links do not perform deletion or editing. Do not infer folder renaming, moving, deletion, file replacement or link deletion.
    Form parsing
    GET uses path and query parameters; POST and PUT read form fields from request.POST, not assumed JSON. File uploads use multipart/form-data; when using JavaScript FormData, do not manually specify Content-Type. Deployed multipart PUT parsing remains to verify.
    Other
    Missing required fields, invalid time zones, invalid numeric or email group identifiers, missing referenced records, storage upload failures, file-size lookup failures, serialization failures and notification submission failures are not handled locally; global error handling determines those responses.
    Partial completion
    A folder is saved before recipient processing; POST upload stores files and creates records before returning; PUT upload creates records before queuing its email. A failure can occur after some work has completed.
    Retries
    No idempotency mechanism is shown. Repeated requests can create duplicate folders, file records or live links and repeat distribution emails. Filename collisions may target the same storage key. Inspect folder contents before retrying an uncertain mutation.

    Pending confirmation: Registered routes /files/copy-skeleton and /files/bulk-actions: view implementations were not supplied, so methods and behavior are not established; LiveLinks model constraints; File distribution-history item schema; get_obj_files output used for email attachments (files processed with expires=604800, uploaded_on=False); Global permission and error handling; Upload limits and accepted file types; Filename collision policy; Confirmation of deployed multipart PUT parsing.

    Module

    Inspections

    Retrieve, create and edit inspections, optionally copy a QA/QC checklist, upload attachments, and add, edit, move or toggle checklist items. Inspection creation and detail edits queue background synchronization into matching main Daily Reports. Correspondences and deletion operations are outside this reference; examples have not been tested against the deployed API.

    List project inspections

    GET/inspections

    Returns project inspections ordered by inspection_date descending. Same-date ordering is not defined. No pagination, status/date-range filters, search or custom sorting is implemented.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerSupply for project listing; presence is not explicitly validated by the view.
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for status calculations and attachment timestamps.
    iso2RequiredstringOnly exact uppercase US selects MM/DD/YYYY; any other value selects DD/MM/YYYY.
    cURL
    curl --get "https://api.jet.build/inspections" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK — array; empty result returns []

    Response
    [
      {
        "pk": 456,
        "title": "Level 2 Framing Inspection",
        "inspection_id": "11111111-1111-4111-8111-111111111111",
        "inspection_date": {
          "date": "11/20/2026",
          "display": "Nov 20, 2026"
        },
        "inspection_by": "Example Inspector",
        "inspection_time": "02:30 PM",
        "status": {
          "status": "UPCOMING",
          "days_overdue": -5
        },
        "bic": {
          "groups": [],
          "users": [
            "inspector@example.com"
          ]
        }
      }
    ]

    Retrieve one inspection

    GET/inspections

    Reads the inspection and its checklist by database primary key. project_pk does not constrain the detail lookup in the supplied view.

    Query parameters

    FieldTypeDescription
    inspection_pkRequiredintegerInspection database primary key, not inspection_id (UUID).
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for status calculations and attachment timestamps.
    iso2RequiredstringOnly exact uppercase US selects MM/DD/YYYY; any other value selects DD/MM/YYYY.
    cURL
    curl --get "https://api.jet.build/inspections" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "inspection_pk=456" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    • Returns Inspection detail — Inspection fields, distribution, responses, files, items, notes and workflow.

    Create an inspection

    POST/inspections

    Creates an open inspection and optionally copies checklist items from a QA/QC list. Creation does not read a submitted status. No created_by field is stored; notifications identify the authenticated user separately.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    titleRequiredstringInspection title; model maximum 2,520 characters.
    notesRequiredstringInspection notes.
    inspection_dateRequiredstringScheduled date in the iso2-selected format. Validate first: invalid input silently becomes the server's current date.
    inspection_timeRequiredhh:mm AM/PMRequired even when empty. Empty or unparseable becomes null; GET returns an empty string when no time is stored.
    inspection_byRequiredstringInspector attribution; maximum 2,520 characters. Not automatically replaced with the authenticated user's identity.
    project_idRequiredintegerProject database identifier.
    linked_listRequiredinteger | NAQA/QC list database pk, not list_id UUID. NA starts with an empty items array.
    project_nameRequiredstringUsed in notifications.
    project_uuidRequiredUUIDUsed in notification links.
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for status calculations and attachment timestamps.
    iso2RequiredstringOnly exact uppercase US selects MM/DD/YYYY; any other value selects DD/MM/YYYY.

    Optional recipients and workflow

    FieldTypeDescription
    intended_forrepeated stringRecipient emails; repeat the field, not JSON arrays or comma-separated values.
    intended_for_groupsrepeated integerRecipient group identifiers, converted to integers.
    wfN_emails, wfN_groupsrepeated valuesWorkflow participants for steps N=1 through 5. Repeat each field for multiple participants.
    wfN_completepresence flagPresent means complete, even with value false. Omit for incomplete.
    cURL
    curl --request POST "https://api.jet.build/inspections" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "title=Level 2 Framing Inspection" \
      --form-string "notes=Review framing before wall closure." \
      --form-string "project_id=123" \
      --form-string "inspection_date=11/20/2026" \
      --form-string "inspection_time=02:30 PM" \
      --form-string "inspection_by=Example Inspector" \
      --form-string "linked_list=NA" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "timezone=America/New_York" \
      --form-string "iso2=US" \
      --form-string "intended_for=manager@example.com" \
      --form-string "wf1_emails=inspector@example.com"

    Response

    200 OK — pk, inspection_id, title, computed status and bic

    Response
    {
      "pk": 456,
      "inspection_id": "11111111-1111-4111-8111-111111111111",
      "title": "Level 2 Framing Inspection",
      "status": {
        "status": "UPCOMING",
        "days_overdue": 0
      },
      "bic": {
        "groups": [],
        "users": [
          "inspector@example.com"
        ]
      }
    }

    Edit inspection details and status

    PUT/inspections

    Replaces title, date, inspector attribution, notes, time, status and the entire workflow. Recipients (ccd), checklist items, project association and existing attachment contents are not replaced.

    Encoding: multipart/form-data

    Form fields

    FieldTypeDescription
    inspection_pkRequiredintegerInspection database primary key, not inspection_id (UUID).
    put_typeRequiredinspectionMust be inspection.
    titleRequiredstringInspection title; model maximum 2,520 characters.
    notesRequiredstringInspection notes.
    inspection_dateRequiredstringScheduled date in the iso2-selected format. Validate first: invalid input silently becomes the server's current date.
    inspection_timeRequiredhh:mm AM/PMRequired even when empty. Empty or unparseable becomes null; GET returns an empty string when no time is stored.
    inspection_byRequiredstringInspector attribution; maximum 2,520 characters. Not automatically replaced with the authenticated user's identity.
    statusRequiredopn | pass | fail | naUse only documented stored codes; the view assigns directly without an explicit allowed-value check.
    iso2RequiredstringOnly exact uppercase US selects MM/DD/YYYY; any other value selects DD/MM/YYYY.
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for status calculations and attachment timestamps.
    project_name, project_uuidConditionalstring, UUIDRead when closing an open inspection, or when it remains/becomes open with bic. Include both consistently.

    Optional replacement workflow

    FieldTypeDescription
    wfN_emails, wfN_groupsrepeated valuesWorkflow participants for steps N=1 through 5. Repeat each field for multiple participants.
    wfN_completepresence flagPresent means complete, even with value false. Omit for incomplete.
    cURL
    curl --request PUT "https://api.jet.build/inspections" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "inspection_pk=456" \
      --form-string "put_type=inspection" \
      --form-string "title=Level 2 Framing Inspection" \
      --form-string "notes=Review framing before wall closure." \
      --form-string "inspection_date=11/20/2026" \
      --form-string "inspection_time=02:30 PM" \
      --form-string "inspection_by=Example Inspector" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "timezone=America/New_York" \
      --form-string "iso2=US" \
      --form-string "wf1_emails=inspector@example.com" \
      --form-string "status=pass" \
      --form-string "wf1_complete=1"

    Response

    200 OK — pk, inspection_id, title, computed status and bic

    Upload inspection attachments

    PUT/inspections

    Appends files to the inspection-level files array. Retrieve inspection details after uploading.

    Encoding: multipart/form-data

    Form fields

    FieldTypeDescription
    inspection_pkRequiredintegerInspection database primary key, not inspection_id (UUID).
    put_typeRequiredfilesMust be files.
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for status calculations and attachment timestamps.
    organization_idRequiredintegerOrganization matching the inspection; consistency is not visibly validated.
    project_idRequiredintegerProject matching the inspection; also used in the storage path.
    filename0, filename1, …RequiredfileBinary files under distinct field names beginning with filename.
    cURL
    curl --request PUT "https://api.jet.build/inspections" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "inspection_pk=456" \
      --form-string "put_type=files" \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_id=123" \
      --form "filename0=@./inspection-photo.jpg" \
      --form "filename1=@./inspection-record.pdf"

    Response

    200 OK — response data is null

    Add a checklist item

    POST/inspections/items/{inspection_id}

    Inserts an incomplete item with no files and repositions all stored items sequentially from 1.

    Encoding: multipart/form-data

    Path parameter

    FieldTypeDescription
    inspection_idRequiredintegerPath parameter is the inspection database primary key. Send the same value as inspection_pk; the view looks up the form field, not the path value.

    Form fields

    FieldTypeDescription
    inspection_pkRequiredintegerInspection database primary key, not inspection_id (UUID).
    positionRequiredintegerOne-based insertion position.
    titleRequiredstringChecklist item title.
    notesRequiredstringChecklist item notes.
    cURL
    curl --request POST "https://api.jet.build/inspections/items/456" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "inspection_pk=456" \
      --form-string "position=1" \
      --form-string "title=Verify framing alignment" \
      --form-string "notes=Review Grid B before wall closure."

    Response

    200 OK — new item

    Response
    {
      "timestamp": 1794236400,
      "position": 1,
      "title": "Verify framing alignment",
      "notes": "Review Grid B before wall closure.",
      "complete": false,
      "files": []
    }

    Edit or move a checklist item

    PUT/inspections/items/{inspection_id}

    Selects an item by zero-based source index and moves it to a one-based destination. Timestamp, completion and attachments are retained; all positions are renumbered.

    Encoding: multipart/form-data

    Path parameter

    FieldTypeDescription
    inspection_idRequiredintegerPath parameter is the inspection database primary key. Send the same value as inspection_pk; the view looks up the form field, not the path value.

    Form fields

    FieldTypeDescription
    inspection_pkRequiredintegerInspection database primary key, not inspection_id (UUID).
    previous_positionRequiredintegerZero-based source array index: 0 selects the first item. Refresh details before addressing positions.
    put_typeRequireditemMust be item.
    new_positionRequiredintegerOne-based destination position.
    titleRequiredstringReplacement title.
    notesRequiredstringReplacement notes.
    cURL
    curl --request PUT "https://api.jet.build/inspections/items/456" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "inspection_pk=456" \
      --form-string "previous_position=0" \
      --form-string "put_type=item" \
      --form-string "new_position=2" \
      --form-string "title=Verify revised framing alignment" \
      --form-string "notes=Include the revised detail at Grid B."

    Response

    200 OK — updated item

    Toggle checklist completion

    PUT/inspections/items/{inspection_id}

    Toggles false to true or true to false. No desired complete value is read. This operation is not idempotent: repeating it reverses the change.

    Encoding: multipart/form-data

    Path parameter

    FieldTypeDescription
    inspection_idRequiredintegerPath parameter is the inspection database primary key. Send the same value as inspection_pk; the view looks up the form field, not the path value.

    Form fields

    FieldTypeDescription
    inspection_pkRequiredintegerInspection database primary key, not inspection_id (UUID).
    previous_positionRequiredintegerZero-based source array index: 0 selects the first item. Refresh details before addressing positions.
    put_typeRequiredcompleteMust be complete.
    cURL
    curl --request PUT "https://api.jet.build/inspections/items/456" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "inspection_pk=456" \
      --form-string "previous_position=0" \
      --form-string "put_type=complete"

    Response

    200 OK — updated item

    Upload checklist item attachments

    PUT/inspections/items/{inspection_id}

    Appends files to the selected item's files array, separate from inspection-level attachments.

    Encoding: multipart/form-data

    Path parameter

    FieldTypeDescription
    inspection_idRequiredintegerPath parameter is the inspection database primary key. Send the same value as inspection_pk; the view looks up the form field, not the path value.

    Form fields

    FieldTypeDescription
    inspection_pkRequiredintegerInspection database primary key, not inspection_id (UUID).
    previous_positionRequiredintegerZero-based source array index: 0 selects the first item. Refresh details before addressing positions.
    put_typeRequiredfilesMust be files.
    timezoneRequiredstringValid IANA time zone, e.g. America/New_York. Used for status calculations and attachment timestamps.
    organization_idRequiredintegerOrganization matching the inspection; consistency is not visibly validated.
    project_idRequiredintegerProject matching the inspection; also used in the storage path.
    filename0, filename1, …RequiredfileBinary files under distinct field names beginning with filename.
    cURL
    curl --request PUT "https://api.jet.build/inspections/items/456" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "inspection_pk=456" \
      --form-string "previous_position=0" \
      --form-string "put_type=files" \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_id=123" \
      --form "filename0=@./alignment-photo.jpg"

    Response

    200 OK — updated item

    Inspections objects

    Inspection detail

    Detail and list responses use different status and Ball-in-Court shapes. Database pk and inspection_id UUID are separate identifiers.

    FieldTypeDescription
    pkRequiredintegerDatabase primary key used for retrieval, updates and item paths.
    inspection_idRequiredUUIDInspection UUID; never submit as inspection_pk.
    titlestringInspection title; model maximum 2,520 characters.
    notesstringInspection notes.
    inspection_dateobjectScheduled date in the iso2-selected format. Validate first: invalid input silently becomes the server's current date.
    inspection_timehh:mm AM/PMRequired even when empty. Empty or unparseable becomes null; GET returns an empty string when no time is stored.
    inspection_bystringInspector attribution; maximum 2,520 characters. Not automatically replaced with the authenticated user's identity.
    statusstringRaw stored inspection status code.
    status_displayobjectComputed status and days_overdue.
    ccdobjectDistribution: groups (integers) and users (emails). Updates do not modify it.
    responsesarrayStored responses with text, user, name, on, timestamp, status and files. No response-writing operation is supplied.
    filesarrayInspection-level stored attachments.
    itemsChecklist item[]Checklist entries in current position order.
    workflow, bicWorkflowStored workflow and workflow-derived Ball in Court.
    Example
    {
      "pk": 456,
      "inspection_id": "11111111-1111-4111-8111-111111111111",
      "title": "Level 2 Framing Inspection",
      "inspection_date": {
        "date": "11/20/2026",
        "display": "Nov 20, 2026"
      },
      "inspection_by": "Example Inspector",
      "inspection_time": "02:30 PM",
      "status": "opn",
      "status_display": {
        "status": "UPCOMING",
        "days_overdue": 0
      },
      "ccd": {
        "groups": [
          12
        ],
        "users": [
          "manager@example.com"
        ]
      },
      "responses": [],
      "files": [],
      "items": [],
      "notes": "Review framing before wall closure.",
      "workflow": [],
      "bic": null
    }

    Checklist item

    Stored/returned positions are one-based and renumber after mutations. PUT selects by zero-based previous_position, not timestamp.

    FieldTypeDescription
    timestampnumberGenerated on creation with second-level resolution; illustrative examples are not unique identifiers.
    positionintegerCurrent one-based stored position.
    titlestringItem title.
    notesstring | nullNull for copied QA/QC items.
    completebooleanInitially false; completion PUT toggles it.
    filesarrayItem-level attachments, separate from inspection files.
    Example
    {
      "timestamp": 1794236400,
      "position": 1,
      "title": "Verify framing alignment",
      "notes": "Review Grid B before wall closure.",
      "complete": false,
      "files": []
    }

    Workflow and Ball in Court

    Up to five steps. Trailing steps without participants are removed; empty intermediate steps remain. No participants produces an empty workflow. Detail PUT replaces the full workflow.

    FieldTypeDescription
    groupsinteger[]Group database identifiers.
    usersstring[]Participant emails.
    completebooleanPresence of wfN_complete marks the step complete, even if submitted as false.
    Example
    [
      {
        "groups": [
          12
        ],
        "users": [
          "inspector@example.com"
        ],
        "complete": false
      }
    ]

    Stored attachment

    Paths are stored, not generated download URLs. Upload timestamps use the supplied time zone.

    FieldTypeDescription
    filestringStorage path.
    filenamestringStored filename.
    uploaded_onstringDisplay timestamp.
    Example
    {
      "file": "10/projects/123/inspections/456/inspection-record.pdf",
      "filename": "inspection-record.pdf",
      "uploaded_on": "Mon Nov 09, 2026 at 03:30 PM"
    }

    Inspections status values

    Stored inspection status

    Creation always defaults to opn. Change status through detail PUT using only these codes.

    opn
    OPEN
    pass
    PASSED
    fail
    FAILED
    na
    NOT APPLICABLE

    Computed status and Ball in Court

    Status uses the inspection date and supplied local date, not whether the scheduled time has passed.

    OVERDUE
    Open inspection before local today; days_overdue is positive (e.g. 3).
    UPCOMING
    Open inspection today has days_overdue=0; future dates have negative values (e.g. -5).
    Non-open
    Display label (PASSED, FAILED or NOT APPLICABLE) with days_overdue=0.
    bic
    First workflow step whose complete is not true, including empty participants. All-complete or empty workflow gives null. An empty incomplete step gives {groups:[], users:[]}. List suppresses non-open bic to null; detail does not; detail PUT returns [] for non-open.

    Stored response status

    Response-level codes are separate from inspection status. No response-writing operation is documented; correspondences are excluded.

    non
    NO INPUT
    pass
    PASSED
    fail
    FAILED

    Daily Report synchronization

    Background processing uses the project city's time zone independently of request timezone. HTTP success does not confirm synchronization.

    Creation
    Appends to every same-project, same-date main report (sub_report=false): position, title, by, time, notes and inspection_id (database pk). Does not create reports, update contractor subreports or visibly deduplicate reruns.
    Editing
    After save, searches main reports at the current project/date and updates the first entry matching the current title, not inspection_id. Renaming may lose the match; date changes leave old entries; no match inserts nothing; same-title entries are ambiguous.
    Limits
    Attachment/checklist mutations do not queue synchronization. Helpers do not explicitly exclude finalized reports and do not write computed status into report entries. Verify report contents when synchronization matters.

    Inspections errors

    401 Unauthorized
    Missing authentication; view response data is null. Additional project/role authorization is not established by the supplied views.
    405
    Unsupported root inspection put_type falls through to HTTP 405.
    Unsupported item PUT
    Use only item, complete or files. The item is removed before put_type is checked; an unsupported value saves the array without reinserting it and returns HTTP 200 with the removed item. Do not rely on error rejection.
    Form parsing
    POST/PUT read request.POST, not assumed JSON. Use form fields; for files use multipart/form-data and distinct filename-prefixed fields. Let FormData supply Content-Type/boundary. Deployed PUT parsing remains to verify.
    Other
    Unknown inspection/list, missing fields, invalid zones/groups/indices, upload or job-submission failures have no locally structured errors; global exception handling determines responses.
    Retries
    No idempotency mechanism. Repeated creation can duplicate inspections/items; uploads append again; completion toggles back; edits can queue further emails/jobs. Reconcile current state before uncertain retries.
    Partial completion
    Inspection may save before notification/time-zone failure; files may upload before save succeeds. A failed request does not establish that nothing changed.
    Concurrent changes
    Checklist operations read/modify/save the whole items array without shown locking/version checks. Coordinate writes and refresh indices to avoid overwriting changes or addressing the wrong item.

    Pending confirmation: Canonical root URL slash behavior (/inspections or /inspections/); item route has no trailing slash; Deployed form parsing for PUT; Global project permissions and error handling; File-size limits and supported types; File download handling; QA/QC list lookup endpoint; Groups and Directory lookup endpoints.

    Module

    Punch Lists

    Retrieve project punch list items or one item with its attachments and responses, create items with or without a linked drawing (optionally pinned to PDF coordinates), and update details, completion state, workflow and attachments — including a limited title/description/completion update. Correspondences and deletion are outside this reference.

    List project punch list items

    GET/punch-lists

    Returns every item for a project, ordered by database primary key descending. No pagination, search, date filtering, completion filtering or custom sorting.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier. The view does not explicitly validate its presence.
    timezoneRequiredstringValid IANA identifier, e.g. America/New_York. Used for status calculations and creation/attachment display timestamps.
    iso2RequiredstringDate-format selector. Only the exact uppercase value US gives MM/DD/YYYY; all other values give DD/MM/YYYY.
    cURL
    curl --get "https://api.jet.build/punch-lists" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK — array (empty result returns [])

    • Returns Punch item[] — Items for the project. bic is workflow-derived when incomplete and null when complete.

    Retrieve one item

    GET/punch-lists?item_pk={item_pk}

    The presence of item_pk selects single-item retrieval. The lookup uses item_pk directly; a project_pk parameter does not constrain it in this view.

    Query parameters

    FieldTypeDescription
    item_pkRequiredintegerItem database identifier.
    timezoneRequiredstringValid IANA identifier, e.g. America/New_York. Used for status calculations and creation/attachment display timestamps.
    iso2RequiredstringDate-format selector. Only the exact uppercase value US gives MM/DD/YYYY; all other values give DD/MM/YYYY.
    cURL
    curl --get "https://api.jet.build/punch-lists" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "item_pk=456" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    Create a standard item

    POST/punch-lists

    Creates an item with an optional linked drawing reference. Do not include from_sheet — its presence (even from_sheet=false) selects drawing-pinned creation.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    titleRequiredstringItem title; model maximum 2,520 characters.
    aboutRequiredstringItem description.
    project_idRequiredintegerProject database identifier.
    created_byRequiredstringStored creator attribution; model maximum 2,520 characters. Stored as submitted — the view does not replace it with the authenticated user's name.
    due_byRequiredstringDue date in the format selected by iso2.
    iso2RequiredstringDate-format selector. Only the exact uppercase value US gives MM/DD/YYYY; all other values give DD/MM/YYYY.
    timezoneRequiredstringValid IANA identifier, e.g. America/New_York. Used for status calculations and creation/attachment display timestamps.
    organization_idRequiredintegerOrganization identifier used for attachment storage paths.
    project_nameRequiredstringProject name used in notifications.
    project_uuidRequiredstring (UUID)Project UUID used in notification links. Separate from project_id.
    new_numberRequiredinteger textItem number, submitted as integer text. The model does not declare item_number unique.
    linked_sheetRequiredstringEncoded drawing reference <discipline>|*|<sheet number>|*|<version>, e.g. 45|*|A-101|*|0, or NA for no drawing. Does not carry pinned coordinates.

    Optional form fields

    FieldTypeDescription
    locationstringModel maximum 360 characters; defaults to null.
    contractorstringModel maximum 360 characters; defaults to null. Stored as a string and returned as responsible_contractor; not resolved into recipient assignments.
    intended_forstring (repeat)Recipient email. Repeat the field for each user.
    intended_for_groupsinteger (repeat)Recipient group identifier; converted to integers. Repeat for each group.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete. Submitting wf1_complete=false still marks the step complete.
    filename0, filename1, …fileAttachments under distinct field names beginning with filename.
    cURL
    curl --request POST "https://api.jet.build/punch-lists" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "title=Repair damaged wall finish" \
      --form-string "about=Repair and repaint the damaged finish near Door 201." \
      --form-string "new_number=27" \
      --form-string "linked_sheet=NA" \
      --form-string "project_id=123" \
      --form-string "created_by=Example User" \
      --form-string "due_by=11/20/2026" \
      --form-string "iso2=US" \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "location=Level 2 Corridor" \
      --form-string "contractor=Example Contractor" \
      --form-string "intended_for=manager@example.com" \
      --form-string "wf1_emails=contractor@example.com" \
      --form "filename0=@./damaged-finish.jpg"

    Response

    200 OK — punch item fields

    • Returns integer — Item database identifier. Submit as item_pk for retrieval and item_object_pk for updates.
    • Returns string — Item title.
    • Returns string — Item description.
    • Returns integer — Item number. Not guaranteed unique; do not use it as a lookup.
    • Returns string (UUID) — Item UUID, separate from the database primary key. Not accepted as a lookup parameter by this endpoint.
    • Returns Due date — Due date object with date and display strings.
    • Returns boolean — Stored completion field.
    • Returns Status — Computed OPEN / OVERDUE / COMPLETE with days_overdue; see status values.
    • Returns string — Stored creator attribution.
    • Returns string — Local display timestamp, no time zone offset.
    • Returns string | null — Stored contractor string.
    • Returns string | null — Stored location.
    • Returns Drawing reference — Linked drawing, or {} when none.
    • Returns Ball in Court | null — Workflow-derived when incomplete; null when complete.

    Create an item pinned to a drawing

    POST/punch-lists

    The presence of from_sheet selects drawing-pinned creation — even from_sheet=false. Omit the field entirely for standard creation. new_number and linked_sheet are not read in this branch.

    Encoding: multipart/form-data

    Required common fields

    FieldTypeDescription
    titleRequiredstringItem title; model maximum 2,520 characters.
    aboutRequiredstringItem description.
    project_idRequiredintegerProject database identifier.
    created_byRequiredstringStored creator attribution; model maximum 2,520 characters. Stored as submitted — the view does not replace it with the authenticated user's name.
    due_byRequiredstringDue date in the format selected by iso2.
    iso2RequiredstringDate-format selector. Only the exact uppercase value US gives MM/DD/YYYY; all other values give DD/MM/YYYY.
    timezoneRequiredstringValid IANA identifier, e.g. America/New_York. Used for status calculations and creation/attachment display timestamps.
    organization_idRequiredintegerOrganization identifier used for attachment storage paths.
    project_nameRequiredstringProject name used in notifications.
    project_uuidRequiredstring (UUID)Project UUID used in notification links. Separate from project_id.

    Required drawing fields

    FieldTypeDescription
    from_sheetRequiredpresence flagInclude (any value) to select pinned creation.
    discipline_pkRequiredintegerDiscipline identifier from the Drawings API.
    sheet_noRequiredstringSheet number.
    version_noRequiredintegerSheet version.
    XRequiredstringPDF coordinate, stored as submitted without numeric conversion.
    YRequiredstringPDF coordinate, stored as submitted without numeric conversion.

    Optional form fields

    FieldTypeDescription
    locationstringModel maximum 360 characters; defaults to null.
    contractorstringModel maximum 360 characters; defaults to null. Stored as a string and returned as responsible_contractor; not resolved into recipient assignments.
    intended_forstring (repeat)Recipient email. Repeat the field for each user.
    intended_for_groupsinteger (repeat)Recipient group identifier; converted to integers. Repeat for each group.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete. Submitting wf1_complete=false still marks the step complete.
    filename0, filename1, …fileAttachments under distinct field names beginning with filename.
    cURL
    curl --request POST "https://api.jet.build/punch-lists" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "title=Repair damaged wall finish" \
      --form-string "about=Repair and repaint the damaged finish near Door 201." \
      --form-string "project_id=123" \
      --form-string "created_by=Example User" \
      --form-string "due_by=11/20/2026" \
      --form-string "iso2=US" \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "from_sheet=1" \
      --form-string "discipline_pk=45" \
      --form-string "sheet_no=A-101" \
      --form-string "version_no=0" \
      --form-string "X=125.5" \
      --form-string "Y=240.0"

    Response

    200 OK — same response fields as standard creation

    Full item update

    PUT/punch-lists

    Replaces multiple fields; this is not a partial update. Omit from_mobile — its presence selects the limited update. Verify deployed form parsing for PUT.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    item_object_pkRequiredintegerItem database identifier for updates (returned as pk). Note the difference from item_pk, used for retrieval.
    titleRequiredstringItem title.
    aboutRequiredstringItem description.
    due_byRequiredstringDue date in the format selected by iso2.
    iso2RequiredstringDate-format selector. Only the exact uppercase value US gives MM/DD/YYYY; all other values give DD/MM/YYYY.
    linked_sheetRequiredstringEncoded drawing reference, or NA to clear the drawing reference and coordinates.
    statusRequiredstringUse exactly complete or incomplete. is_complete is set true only when status is exactly complete; every other value sets false.
    timezoneRequiredstringValid IANA identifier, e.g. America/New_York. Used for status calculations and creation/attachment display timestamps.
    organization_idRequiredintegerOrganization identifier.
    project_idRequiredintegerProject database identifier.

    Conditionally required when status=incomplete and Ball in Court exists

    FieldTypeDescription
    project_nameConditionalstringUsed in the Ball-in-Court email.
    project_uuidConditionalstring (UUID)Used in notification links.

    Optional form fields

    FieldTypeDescription
    locationstringOmission resets it to null.
    contractorstringOmission resets responsible_contractor to null.
    wf1_emails … wf5_emails / wf1_groups … wf5_groups / wf1_complete … wf5_completerepeated / presence flagsReplace the complete workflow. Omitting all workflow participants clears it — resend the full workflow to preserve it.
    filename0, filename1, …fileAttachments are appended, not replaced.
    cURL
    curl --request PUT "https://api.jet.build/punch-lists" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "item_object_pk=456" \
      --form-string "title=Repair damaged wall finish" \
      --form-string "about=Repair and repaint the finish near Door 201." \
      --form-string "due_by=11/23/2026" \
      --form-string "iso2=US" \
      --form-string "linked_sheet=NA" \
      --form-string "status=incomplete" \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_id=123" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "location=Level 2 Corridor" \
      --form-string "contractor=Example Contractor" \
      --form-string "wf1_emails=contractor@example.com"

    Response

    200 OK — response data is null; retrieve the item again for updated details

    Limited update (title, description, completion)

    PUT/punch-lists

    The presence of from_mobile selects the limited branch — even from_mobile=false. Despite the name, the branch is selected by the form field rather than the client platform. Omit the field for full updates.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    item_object_pkRequiredintegerItem database identifier for updates (returned as pk). Note the difference from item_pk, used for retrieval.
    from_mobileRequiredpresence flagInclude (any value) to select the limited update.
    titleRequiredstringItem title.
    aboutRequiredstringItem description.
    statusRequiredstringUse exactly complete or incomplete.
    cURL
    curl --request PUT "https://api.jet.build/punch-lists" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "item_object_pk=456" \
      --form-string "from_mobile=1" \
      --form-string "title=Repair damaged wall finish" \
      --form-string "about=Repair completed and ready for verification." \
      --form-string "status=complete"

    Response

    200 OK — response data is null

    Punch Lists objects

    Punch item

    List item and standard-creation response shape.

    FieldTypeDescription
    pkintegerItem database identifier. Submit as item_pk for retrieval and item_object_pk for updates.
    titlestringItem title.
    aboutstringItem description.
    item_numberintegerItem number. Not guaranteed unique; do not use it as a lookup.
    item_idstring (UUID)Item UUID, separate from the database primary key. Not accepted as a lookup parameter by this endpoint.
    due_byDue dateDue date object with date and display strings.
    is_completebooleanStored completion field.
    statusStatusComputed OPEN / OVERDUE / COMPLETE with days_overdue; see status values.
    created_bystringStored creator attribution.
    sent_on_localstringLocal display timestamp, no time zone offset.
    responsible_contractorstring | nullStored contractor string.
    locationstring | nullStored location.
    sheetDrawing referenceLinked drawing, or {} when none.
    bicBall in Court | nullWorkflow-derived when incomplete; null when complete.
    Example
    {
      "pk": 456,
      "title": "Repair damaged wall finish",
      "about": "Repair and repaint the damaged finish near Door 201.",
      "item_number": 27,
      "item_id": "22222222-2222-4222-8222-222222222222",
      "due_by": { "date": "11/20/2026", "display": "Nov 20, 2026" },
      "is_complete": false,
      "status": "OPEN",
      "days_overdue": -5,
      "created_by": "Example User",
      "sent_on_local": "Mon Nov 09, 2026 at 03:30 PM",
      "responsible_contractor": "Example Contractor",
      "location": "Level 2 Corridor",
      "sheet": { "discipline": "45", "number": "A-101", "version": "0" },
      "bic": { "groups": [12], "users": ["contractor@example.com"] }
    }

    Punch item detail

    Single-item GET response. Adds ccd, responses, file, workflow and distributions; returns workflow instead of bic. Constructed directly by the view rather than the model's separate get_details method.

    FieldTypeDescription
    pkintegerItem database identifier. Submit as item_pk for retrieval and item_object_pk for updates.
    titlestringItem title.
    aboutstringItem description.
    item_numberintegerItem number. Not guaranteed unique; do not use it as a lookup.
    item_idstring (UUID)Item UUID, separate from the database primary key. Not accepted as a lookup parameter by this endpoint.
    due_byDue dateDue date object with date and display strings.
    is_completebooleanStored completion field.
    statusStatusComputed OPEN / OVERDUE / COMPLETE with days_overdue; see status values.
    created_bystringStored creator attribution.
    sent_on_localstringLocal display timestamp, no time zone offset.
    responsible_contractorstring | nullStored contractor string.
    locationstring | nullStored location.
    sheetDrawing referenceLinked drawing, or {} when none.
    ccdRecipientsDistribution recipients from intended_for / intended_for_groups. Neither update mode modifies ccd.
    responsesPunch response[]Transformed responses.
    filePunch attachment[]Singular field name containing an array.
    workflowWorkflowStep[]Up to five workflow steps.
    distributionsarrayStored distribution history returned directly; its item schema is not established by the supplied code.
    Example
    {
      "pk": 456,
      "title": "Repair damaged wall finish",
      "item_number": 27,
      "status": "OVERDUE",
      "days_overdue": 3,
      "ccd": { "groups": [12, 34], "users": ["manager@example.com", "owner@example.com"] },
      "responses": [
        { "text": "Work corrected.", "user": "contractor@example.com", "name": "Example Contractor", "on": "11/12/2026", "status": "WORK CORRECTED", "timestamp": 1794236400, "files": [] }
      ],
      "file": [
        { "file": "10/projects/123/punches/1794236400/photo.jpg", "filename": "photo.jpg", "uploaded_on": "Mon Nov 09, 2026 at 03:30 PM", "document_url": "<presigned download URL>" }
      ],
      "workflow": [
        { "groups": [12], "users": ["contractor@example.com"], "complete": false }
      ],
      "distributions": []
    }

    Punch attachment

    Item attachment in the detail response's file array. Storage paths follow <organization_id>/projects/<project_id>/punches/<creation_timestamp>/<filename> — the storage component is punches while the API endpoint is punch-lists.

    FieldTypeDescription
    filestringRelative storage path. Not a public download URL.
    filenamestringStored filename.
    uploaded_onstringLocal display timestamp, no time zone offset.
    document_urlstringPresigned download URL with a default requested expiration of 900 seconds (15 minutes). Use it directly; retrieve item details again for a fresh URL. Email attachment processing requests 604800 seconds (seven days).
    Example
    {
      "file": "10/projects/123/punches/1794236400/photo.jpg",
      "filename": "photo.jpg",
      "uploaded_on": "Mon Nov 09, 2026 at 03:30 PM",
      "document_url": "<presigned download URL>"
    }

    Punch response

    Transformed item response. Response status is separate from the item's completion state. No response-writing operation is documented.

    FieldTypeDescription
    textstringResponse text.
    userstringResponding user's email.
    namestringResponding user's name.
    onstringDisplay date.
    statusstringDisplay label mapped from the stored code: non → NO OFFICIAL INPUT, dis → DISPUTE ITEM, wrk → WORK CORRECTED. An unrecognized code returns null.
    timestampintegerResponse timestamp.
    filesPunch attachment[]Response attachments; their uploaded_on is an empty string and document_url uses the default 15-minute requested expiration.
    Example
    {
      "text": "Work corrected.",
      "user": "contractor@example.com",
      "name": "Example Contractor",
      "on": "11/12/2026",
      "status": "WORK CORRECTED",
      "timestamp": 1794236400,
      "files": []
    }

    Drawing reference

    Linked drawing stored on an item. Components are stored as strings; the view does not visibly validate the referenced drawing.

    FieldTypeDescription
    disciplinestringDiscipline identifier from the Drawings API.
    numberstringSheet number.
    versionstringSheet version.
    XstringPinned PDF coordinate; present only for drawing-pinned creation.
    YstringPinned PDF coordinate; present only for drawing-pinned creation.
    Example
    {
      "discipline": "45",
      "number": "A-101",
      "version": "0",
      "X": "125.5",
      "Y": "240.0"
    }

    Punch Lists status values

    Computed status

    days_overdue is the local date minus the due date: negative values indicate a future due date, zero indicates an item due today.

    COMPLETE
    is_complete is true; days_overdue is 0.
    OVERDUE
    Incomplete and due_by is before the supplied local date; days_overdue is positive.
    OPEN
    Incomplete and due_by is today or later; days_overdue is zero or negative. The creation response always uses OPEN, even when a subsequent GET returns OVERDUE.

    Update status values

    The view sets is_complete=true only when status is exactly complete; every other submitted value sets is_complete=false. Full-update notification behavior specifically checks for incomplete.

    complete
    Marks the item complete.
    incomplete
    Marks the item incomplete; queues Ball-in-Court email processing when bic exists.

    Identifiers and field names

    Database primary keys, item numbers and UUIDs are separate values.

    project_pk / project_id
    Project database identifier: project_pk for listing, project_id for creation and full updates.
    item_pk / item_object_pk
    Item database identifier (returned as pk): item_pk for single-item retrieval, item_object_pk for updates.
    item_id
    Item UUID. This endpoint does not accept it as a lookup parameter.
    new_number / item_number
    new_number during standard creation; returned as item_number. Drawing-pinned creation generates it automatically. Not guaranteed unique.
    contractor / responsible_contractor
    Submitted as contractor; returned as responsible_contractor. Stored as a string, not resolved into recipient assignments.

    Presence flags

    These branches are selected by the field's presence, not its value.

    from_sheet
    Selects drawing-pinned creation — even from_sheet=false. Omit entirely for standard creation.
    from_mobile
    Selects the limited update — even from_mobile=false. Omit for full updates.
    wfN_complete
    Marks workflow step N complete — even with value false. Omit for incomplete.

    Punch Lists errors

    401 Unauthorized
    Unauthenticated requests; the view sets response data to null. Additional project and role authorization is not established by the supplied view.
    Unsupported methods
    Only GET, POST and PUT are declared. DELETE is not supported by this view; no item deletion operation is implemented.
    Form parsing
    GET uses query parameters. POST and PUT read form fields from request.POST — do not assume application/json bodies are supported. Attachments use multipart/form-data; when using JavaScript FormData, do not manually specify Content-Type. Deployed form parsing, especially for PUT, remains to verify.
    Dates
    An unparseable date silently becomes the server's current date under the shared date parser. Only the exact uppercase value US selects month-first parsing. Validate dates before submission.
    Retries
    No idempotency mechanism is shown. Repeated POST requests can create duplicate items and trigger additional notifications; repeated full updates containing files can append attachments again; repeated incomplete-item updates can send additional Ball-in-Court emails. Reconcile current item state before retrying uncertain writes.
    Partial completion
    Creation saves the item before activity logging and notification submission; full updates save before their conditional logging and email processing. A request can fail after data has already been stored.
    Other
    Unknown item identifiers, missing required fields, invalid time zones, invalid group identifiers, malformed drawing references, storage failures and notification submission failures are not handled locally; global error handling determines those responses. Do not assume unknown items return a particular 404 response.

    Pending confirmation: Canonical root URL slash behavior; Deployed form parsing for PUT; Global permissions and error responses; Upload limits and accepted file types; PDF coordinate origin, rotation handling and bounds; Distribution-history item schema; Groups and Directory lookup endpoints.

    Module

    RFIs

    List, retrieve, create and update RFIs — including attachments, distribution recipients, linked drawings and five-step workflow / Ball in Court.

    List RFIs for a project

    GET/rfis

    Ordered by descending pk. No pagination, search or filters.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier.
    timezoneRequiredstringe.g. America/New_York.
    iso2RequiredstringDate-format selector, e.g. US.
    cURL
    curl --get "https://api.jet.build/rfis" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    Retrieve one RFI

    GET/rfis?rfi_pk={rfi_pk}

    Including rfi_pk returns one RFI instead of a list. The UUID (rfi_id) is not accepted.

    Query parameters

    FieldTypeDescription
    rfi_pkRequiredintegerRFI database identifier.
    timezoneRequiredstringTime zone for status calculations.
    iso2RequiredstringDate-format selector.
    cURL
    curl --get "https://api.jet.build/rfis" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "rfi_pk=456" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    • Returns RfiDetail — See the RFI detail object.

    Create an RFI

    POST/rfis

    The caller supplies the RFI number and subnumber. New RFIs default to open.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    rfi_titleRequiredstringMax 152 characters.
    new_numberRequiredinteger textRFI number.
    sub_rfi_numberRequiredinteger textRFI subnumber.
    aboutRequiredstringQuestion or description.
    project_idRequiredintegerProject database identifier.
    created_byRequiredstringCreator display value, stored as sent.
    due_byRequireddate stringFormat follows iso2.
    iso2RequiredstringDate-format selector.
    timezoneRequiredstringLocal time zone.
    linked_sheetRequiredstringdiscipline|*|number|*|version, or NA.
    organization_idRequiredintegerUsed for attachment paths.
    project_nameRequiredstringUsed in notifications.
    project_uuidRequiredstringUsed in notification links.

    Optional form fields

    FieldTypeDescription
    cost_impactstringDefaults to "0.00".
    schedule_impactstringDays. Defaults to "0.00".
    from_contractorstringDefaults to null.
    is_bid_rfipresence flagPresent = true (even "false"). Omit for false.
    intended_forstring (repeat)Recipient email. Repeat the field for each user.
    intended_for_groupsinteger (repeat)Recipient group pk. Repeat the field for each group.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete.
    filename0, filename1, …fileDistinct field name per file.
    cURL
    curl --request POST "https://api.jet.build/rfis" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "rfi_title=Clarify slab edge detail" \
      --form-string "new_number=27" \
      --form-string "sub_rfi_number=0" \
      --form-string "about=Please confirm the slab edge dimension at Grid B." \
      --form-string "project_id=123" \
      --form-string "created_by=Example User" \
      --form-string "due_by=11/05/2026" \
      --form-string "iso2=US" \
      --form-string "timezone=America/New_York" \
      --form-string "linked_sheet=NA" \
      --form-string "organization_id=10" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "intended_for=manager@example.com" \
      --form-string "wf1_emails=architect@example.com" \
      --form "filename0=@./detail.pdf"

    Response

    200 OK

    • Returns RfiCreated — See the RFI created object.

    Update, close or reopen an RFI

    PUT/rfis

    Not a partial update — send every field you want to keep. Omitted optional values reset to defaults and omitted workflow fields clear the workflow.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    rfi_object_pkRequiredintegerRFI database identifier.
    rfi_titleRequiredstringReplacement title.
    aboutRequiredstringReplacement description.
    due_byRequireddate stringReplacement due date.
    iso2RequiredstringDate-format selector.
    linked_sheetRequiredstringReference, or NA to clear.
    statusRequiredenumopn or cls.
    timezoneRequiredstringLocal time zone.
    organization_idRequiredintegerMust match the RFI.
    project_idRequiredintegerMust match the RFI.
    project_nameConditionalstringNeeded when status is opn.
    project_uuidConditionalstringNeeded when status is opn.

    Optional (omission resets)

    FieldTypeDescription
    cost_impactstringOmitted → "0.00".
    schedule_impactstringOmitted → "0.00".
    from_contractorstringOmitted → null.
    is_bid_rfipresence flagOmitted → false.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete.
    filename0, …fileAppended to existing attachments.
    cURL
    curl --request PUT "https://api.jet.build/rfis" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "rfi_object_pk=456" \
      --form-string "rfi_title=Clarify slab edge detail" \
      --form-string "about=Please confirm the revised slab edge dimension." \
      --form-string "due_by=11/06/2026" \
      --form-string "iso2=US" \
      --form-string "linked_sheet=NA" \
      --form-string "status=opn" \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_id=123" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "wf1_emails=architect@example.com"

    Response

    200 OK — body null

    RFIs objects

    RFI list item

    Item returned by GET /rfis?project_pk=…

    FieldTypeDescription
    pkintegerDatabase identifier.
    rfi_idstring (UUID)Not accepted for lookups.
    titlestringRFI title.
    numberintegerRFI number.
    sub_numberintegerRFI subnumber.
    due_byDueDateFormatted date.
    is_openbooleanOpen state.
    statusStatusComputed status.
    created_bystringStored creator.
    sent_on_localstringCreation display timestamp.
    updated_atstringModel update timestamp.
    sheetLinkedSheet | {}Linked drawing or empty object.
    from_contractorstring | nullContractor.
    bicBallInCourt | nullNull when closed.
    Example
    {
      "pk": 456,
      "rfi_id": "33333333-3333-4333-8333-333333333333",
      "title": "Clarify slab edge detail",
      "number": 27,
      "sub_number": 0,
      "due_by": { "date": "11/05/2026", "display": "Nov 05, 2026" },
      "is_open": true,
      "status": { "status": "OPEN", "days_overdue": -8 },
      "created_by": "Example User",
      "sent_on_local": "Wed Oct 28, 2026 at 03:30 PM",
      "updated_at": "…",
      "sheet": {},
      "from_contractor": null,
      "bic": { "groups": [], "users": ["architect@example.com"] }
    }

    RFI detail

    Returned by GET /rfis?rfi_pk=… It omits rfi_id, number, sub_number, created_by, sent_on_local, updated_at and bic — keep list data if you need them.

    FieldTypeDescription
    pkstringSubmitted identifier, returned as a string.
    titlestringRFI title.
    aboutstringQuestion or description.
    is_openbooleanOpen state.
    is_bid_rfibooleanBid RFI flag.
    from_contractorstring | nullContractor.
    cost_impactstring | nullCost impact.
    schedule_impactstring | nullSchedule impact (days).
    due_byDueDateFormatted date.
    statusStatusComputed status.
    tagsstringTags text.
    sheetLinkedSheetLinked drawing.
    ccdRecipientsDistribution recipients.
    responsesRfiResponse[]Stored responses.
    fileAttachment[]Singular name, array value.
    workflowWorkflowStep[]Workflow steps.
    distributionsarrayDistribution records. Schema pending confirmation.
    Example
    {
      "pk": "456",
      "title": "Clarify slab edge detail",
      "about": "Please confirm the slab edge dimension at Grid B.",
      "is_open": true,
      "is_bid_rfi": false,
      "from_contractor": null,
      "cost_impact": "0.00",
      "schedule_impact": "0.00",
      "due_by": { "date": "11/05/2026", "display": "Nov 05, 2026" },
      "status": { "status": "OPEN", "days_overdue": -8 },
      "tags": "",
      "sheet": {},
      "ccd": { "groups": [], "users": ["manager@example.com"] },
      "responses": [],
      "file": [],
      "workflow": [{ "groups": [], "users": ["architect@example.com"], "complete": false }],
      "distributions": []
    }

    RFI created

    Returned by POST /rfis. number and sub_number may be strings here — normalize them. Status is always OPEN in this response.

    FieldTypeDescription
    pkintegerNew database identifier.
    rfi_idstring (UUID)RFI UUID.
    titlestringTitle.
    numberstring | integerAs submitted.
    sub_numberstring | integerAs submitted.
    due_byDueDateFormatted date.
    is_openbooleanTrue.
    statusStatusOPEN with days_overdue.
    created_bystringCreator.
    sent_on_localstringCreation display timestamp.
    sheetLinkedSheet | {}Linked drawing.
    ball_in_courtBallInCourtNamed ball_in_court here, bic in lists.
    Example
    {
      "pk": 456,
      "rfi_id": "33333333-3333-4333-8333-333333333333",
      "title": "Clarify slab edge detail",
      "number": "27",
      "sub_number": "0",
      "due_by": { "date": "11/05/2026", "display": "Nov 05, 2026" },
      "is_open": true,
      "status": { "status": "OPEN", "days_overdue": -8 },
      "created_by": "Example User",
      "sent_on_local": "Wed Oct 28, 2026 at 03:30 PM",
      "sheet": {},
      "ball_in_court": { "groups": [], "users": ["architect@example.com"] }
    }

    Linked sheet

    Sent as linked_sheet = "discipline|*|number|*|version" (or NA for none). Stored as strings; not validated against Drawings.

    FieldTypeDescription
    disciplinestringDiscipline component.
    numberstringSheet number.
    versionstringVersion.
    Example
    // linked_sheet = 45|*|A-101|*|0
    { "discipline": "45", "number": "A-101", "version": "0" }

    RFI response

    Read-only through this API — the endpoint does not add or accept responses.

    FieldTypeDescription
    textstringResponse text.
    userstringResponder email.
    namestringResponder name.
    onstringDisplay timestamp.
    acceptedbooleanAccepted state.
    accepted_bystring | nullAccepting user.
    accepted_onstring | nullFormat pending confirmation.
    timestampintegerUnix timestamp.
    filesarray{ file, filename } items.
    Example
    {
      "text": "Please use the revised detail.",
      "user": "architect@example.com",
      "name": "Example Architect",
      "on": "Wed Oct 28, 2026 at 04:15 PM",
      "accepted": false,
      "accepted_by": null,
      "accepted_on": null,
      "timestamp": 1793218500,
      "files": [{ "file": "example/path/revised-detail.pdf", "filename": "revised-detail.pdf" }]
    }

    RFIs status values

    status (PUT request)

    opn
    Open or reopen. Queues an activity log and Ball-in-Court emails.
    cls
    Close the RFI.

    status.status (responses)

    Open labels on GET are computed by the overdue helper; the full label list is pending confirmation.

    OPEN
    Always returned by the create response.
    CLOSED
    Closed RFI. days_overdue is 0.

    RFIs errors

    401 Unauthorized
    Missing or invalid token.
    Other
    Missing fields, unknown ids, bad time zones and upload failures are not handled locally.
    Invalid date
    Silently replaced with the server's current date — validate before sending.

    Module

    Submittals

    A submittal is a parent record with one or more versions. List a project's submittals grouped with their versions, read a parent or a single version, create a submittal with Version 1, add versions and update an existing version.

    List project submittals and versions

    GET/submittals

    Returns parents grouped with their matching versions. Parents are ordered by descending pk; versions by descending version number. Parents with no matching versions are omitted. No pagination, search or client sorting.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier. Not explicitly validated by the view — always supply it.
    timezoneRequiredstringIANA time zone used for status calculation.
    iso2RequiredstringDate-format selector. Recommended on every request; omitted falls back to DD/MM/YYYY.
    filtered_specstringFilter versions by their parent's specification. Overrides accepted_only.
    accepted_onlypresence flagPresence selects versions with accepted_final=true. accepted_only=false still enables the filter.
    cURL
    curl --get "https://api.jet.build/submittals" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK — array of grouped records ([] when empty)

    • Returns integer — Parent database identifier.
    • Returns string — <specification title> <name>, or #<number> <name> without a specification.
    • Returns any — Read from the parent's bic attribute.
    • Returns integer — Version database identifier (use for GET/PUT versions).
    • Returns object — { version, display } — display is zero-padded below 10.
    • Returns string — Version UUID. Separate from pk; not accepted by version lookup.
    • Returns object — { status, display }. display structure pending confirmation — do not assume a string.
    • Returns object — Date objects. Absent received date is { date: null, display: "" }.
    • Returns any — Acceptance fields. Types pending confirmation.
    • Returns any — Workflow-derived; only when status=opn and accepted_final=false, otherwise null.
    Response
    [
      {
        "submittal": {
          "pk": 456,
          "number": "27",
          "title": "Interior Door Hardware",
          "display": "#27 Interior Door Hardware",
          "specification": null,
          "specification_sbm_number": null,
          "status": { "status": "...", "display": "..." },
          "responsible": null,
          "bic": null
        },
        "versions": [
          {
            "pk": 789,
            "version": { "version": 1, "display": "01" },
            "version_id": "VERSION_UUID",
            "about": "Product data and hardware schedule for review.",
            "status": { "status": "opn", "display": "..." },
            "due_by": { "date": "11/20/2026", "display": "Nov 20, 2026" },
            "received_on": { "date": null, "display": "" },
            "created_by": "Example User",
            "sent_on_local": "...",
            "accepted_final": false,
            "accepted_by": null,
            "accepted_on": null,
            "bic": "..."
          }
        ]
      }
    ]

    Retrieve a parent submittal

    GET/submittals

    Returns parent details plus settings from the version with the highest version number.

    Query parameters

    FieldTypeDescription
    submittal_pkRequiredintegerParent submittal database identifier.
    iso2RequiredstringDate-format selector. timezone is not required.
    cURL
    curl --get "https://api.jet.build/submittals" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "submittal_pk=456" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    • Returns string — Submitted parent identifier, returned as a string.
    • Returns string — Parent name and number.
    • Returns object — { status, display } for the parent.
    • Returns string — Without a specification: #<number>.<formatted version> <name> (differs from the list).
    • Returns object — Parent due date as a date object.
    • Returns any — Stored specification values.
    • Returns any — Responsible contractor.
    • Returns any — Read from the parent's ball_in_court attribute (the list reads bic).
    • Returns any — Stored values.
    • Returns object — Latest version number, ccd and workflow. Does not include the version pk or UUID.

    Create a submittal and Version 1

    POST/submittals

    Saves the parent, then creates Version 1 through the shared version helper.

    Encoding: multipart/form-data

    Required parent fields

    FieldTypeDescription
    submittal_nameRequiredstringParent submittal name.
    new_numberRequiredstringParent number. Not generated automatically.
    project_idRequiredintegerProject database identifier.
    registry_itemRequiredstringEncoded registry reference, or NA. Format pending confirmation — do not invent values.

    Optional / conditional parent fields

    FieldTypeDescription
    spec_sectionstringSpecification reference. Omit or NA for none.
    specification_sbm_numberConditionalinteger stringRequired when spec_section is present and not NA. Unparseable values become 0.
    responsible_contractorstringStored responsible contractor. Defaults to null.

    Required Version 1 fields

    FieldTypeDescription
    aboutRequiredstringVersion description.
    due_byRequireddate stringFormat follows iso2.
    iso2RequiredstringDate-format selector.
    timezoneRequiredstringIANA time zone for local display timestamps.
    created_byRequiredstringCreator value to store.
    organization_idRequiredintegerUsed for attachment paths.
    project_nameRequiredstringUsed in notifications.
    project_uuidRequiredstringUsed in notification links.

    Optional Version 1 fields

    FieldTypeDescription
    received_ondate stringDate received.
    intended_forstring (repeat)Recipient email. Repeat the field for each user.
    intended_for_groupsinteger (repeat)Recipient group pk. Repeat the field for each group.
    filename0, filename1 …fileEach attachment under a distinct field name beginning with filename.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete.
    curl --request POST "https://api.jet.build/submittals" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "submittal_name=Interior Door Hardware" \
      --form-string "new_number=27" \
      --form-string "project_id=123" \
      --form-string "registry_item=NA" \
      --form-string "spec_section=NA" \
      --form-string "about=Product data and hardware schedule for review." \
      --form-string "due_by=11/20/2026" \
      --form-string "received_on=11/09/2026" \
      --form-string "iso2=US" \
      --form-string "timezone=America/New_York" \
      --form-string "created_by=Example User" \
      --form-string "organization_id=10" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "intended_for=manager@example.com" \
      --form-string "wf1_emails=architect@example.com" \
      --form "filename0=@./product-data.pdf"

    Response

    200 OK — response data is null

    Retrieve a version

    GET/submittals/versions

    Returns one version by its database primary key (not its UUID).

    Query parameters

    FieldTypeDescription
    pkRequiredintegerVersion database primary key.
    iso2RequiredstringDate-format selector. timezone is not required.
    cURL
    curl --get "https://api.jet.build/submittals/versions" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "pk=789" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    • Returns integer — Scalar version number (an object in the list).
    • Returns string — Raw stored status (an object in the list).
    • Returns string | null — Date strings, not date objects.
    • Returns object — Stored recipient groups and user emails.
    • Returns any — Result of get_responses(). Schema pending confirmation.
    • Returns any — Result of get_obj_files(). URL fields and expiry pending confirmation.
    • Returns integer — Parent database identifier.
    • Returns WorkflowStep[] — Stored workflow.
    Response
    {
      "pk": 789,
      "version": 1,
      "about": "Product data and hardware schedule for review.",
      "timestamp": "...",
      "status": "opn",
      "ccd": { "groups": [12], "users": ["manager@example.com"] },
      "due_by": "11/20/2026",
      "received_on": null,
      "responses": [],
      "files": [],
      "submittal_id": 456,
      "workflow": [ { "groups": [], "users": ["architect@example.com"], "complete": false } ]
    }

    Create another version

    POST/submittals/versions

    Adds a version under an existing parent identified by submittal_object_pk.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    submittal_object_pkRequiredintegerExisting parent database identifier.
    new_version_numberRequiredintegerCaller-supplied. Not auto-incremented or checked against existing versions.
    aboutRequiredstringVersion description.
    due_byRequireddate stringFormat follows iso2.
    iso2RequiredstringDate-format selector.
    timezoneRequiredstringIANA time zone.
    created_byRequiredstringCreator value to store.
    project_idRequiredintegerMust match the parent's project (not visibly validated).
    organization_idRequiredintegerUsed for attachment paths.
    project_nameRequiredstringUsed in notifications.
    project_uuidRequiredstringUsed in notification links.

    Optional form fields

    FieldTypeDescription
    received_ondate stringDate received.
    intended_forstring (repeat)Recipient email. Repeat the field for each user.
    intended_for_groupsinteger (repeat)Recipient group pk. Repeat the field for each group.
    filename0, filename1 …fileEach attachment under a distinct field name beginning with filename.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete.
    cURL
    curl --request POST "https://api.jet.build/submittals/versions" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "submittal_object_pk=456" \
      --form-string "new_version_number=2" \
      --form-string "about=Revised product data addressing review comments." \
      --form-string "due_by=11/25/2026" \
      --form-string "iso2=US" \
      --form-string "timezone=America/New_York" \
      --form-string "created_by=Example User" \
      --form-string "project_id=123" \
      --form-string "organization_id=10" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "intended_for=manager@example.com" \
      --form-string "wf1_emails=architect@example.com" \
      --form "filename0=@./revised-product-data.pdf"

    Response

    200 OK — response data is null

    Update a version

    PUT/submittals/versions

    Replaces due date, received date, status, description and workflow, and appends attachments. Not a partial update.

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    version_object_pkRequiredintegerVersion database identifier.
    due_byRequireddate stringReplacement due date.
    iso2RequiredstringDate-format selector.
    statusRequiredstringReplacement stored status code. Valid codes pending confirmation.
    timezoneRequiredstringUpload display timestamp time zone.
    organization_idRequiredintegerUsed for attachment paths.
    project_idRequiredintegerAttachment paths and open-status activity logging.

    Conditional and optional fields

    FieldTypeDescription
    project_nameConditionalstringNeeded when status=opn triggers Ball-in-Court email.
    project_uuidConditionalstringNeeded when status=opn triggers Ball-in-Court email.
    aboutstringOmission resets the description to an empty string.
    received_ondate stringOmission clears it to null. An empty value does not clear it.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete.
    filename0, filename1 …fileNew files are appended.
    cURL
    curl --request PUT "https://api.jet.build/submittals/versions" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "version_object_pk=789" \
      --form-string "due_by=11/27/2026" \
      --form-string "received_on=11/09/2026" \
      --form-string "iso2=US" \
      --form-string "status=opn" \
      --form-string "about=Updated review package." \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_id=123" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "wf1_emails=architect@example.com"

    Response

    200 OK — response data is null

    Submittals objects

    Submittal and versions

    The parent stores name, number, specification, responsible contractor and registry reference. Each version stores its own description, dates, status, recipients, workflow, attachments and responses.

    FieldTypeDescription
    submittal_pk / submittal_object_pk / submittal.pk / submittal_idintegerParent database identifier, under different names per operation.
    versions[].pk / pk / version_object_pkintegerVersion database identifier.
    version_idUUIDVersion UUID, separate from pk.
    versionintegerVersion number. Version 1 is created with the parent.
    workflowWorkflowStep[]Up to five steps per version.
    Example
    Submittal #27 (pk 456)
    ├── Version 02 (pk 790)
    └── Version 01 (pk 789)

    Stored version file

    Stored per uploaded attachment. Path: <organization_id>/projects/<project_id>/submittals/<parent_pk>/<timestamp>/<filename>.

    FieldTypeDescription
    filestringStorage path.
    filenamestringStored filename.
    uploaded_onstringLocal upload display timestamp.
    Example
    {
      "file": "10/projects/123/submittals/456/<timestamp>/product-data.pdf",
      "filename": "product-data.pdf",
      "uploaded_on": "..."
    }

    Submittals status values

    Workflow completion

    wfN_complete present
    Step N is complete (wfN_complete=false still counts as complete).
    wfN_complete omitted
    Step N is incomplete.
    No participants
    Produces an empty workflow; PUT replaces the whole workflow.

    List filters

    filtered_spec
    Versions whose parent matches the specification. Takes precedence.
    accepted_only (present)
    Versions with accepted_final=true, regardless of value.
    status=opn on PUT
    Triggers open-version activity log and applicable Ball-in-Court emails.

    Submittals errors

    401 Unauthorized
    Missing or invalid token. Response data is null.
    404 Not Found
    Parent detail request with no versions for that parent.
    Other
    Missing fields, unknown versions, bad time zones, group ids, uploads or version numbers are handled by global exception handling.
    Invalid date
    Silently replaced with the server's current date — validate before sending.
    Partial completion
    No transaction wrapper. A parent, version or file may exist after a failure.

    Pending confirmation: Exact registered endpoint paths and trailing slashes; status choices, display structures and model constraints; parent bic vs ball_in_court equivalence; responses and files item schemas; update_contractor_recipients behavior and registry reference format; final-acceptance and response endpoints; multipart PUT parsing and request limits.

    Module

    Tasks

    List, retrieve and create tasks, with attachments, distribution recipients, workflow / Ball in Court and optional links to closeout trades or meeting topics.

    List tasks for a project

    GET/tasks

    Ordered by descending pk. Always supply project_pk.

    Query parameters

    FieldTypeDescription
    project_pkRequiredintegerProject database identifier.
    timezoneRequiredstringTime zone for status calculations.
    iso2RequiredstringDate-format selector.
    cURL
    curl --get "https://api.jet.build/tasks" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "project_pk=123" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    Retrieve one task

    GET/tasks?task_pk={task_pk}

    Returns the raw stored status, not a computed status object. No attachments in this response.

    Query parameters

    FieldTypeDescription
    task_pkRequiredintegerTask database identifier.
    timezoneRequiredstringRequired even though not used for status.
    iso2RequiredstringDate-format selector.
    cURL
    curl --get "https://api.jet.build/tasks" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --data-urlencode "task_pk=456" \
      --data-urlencode "timezone=America/New_York" \
      --data-urlencode "iso2=US"

    Response

    200 OK

    • Returns TaskDetail — See the Task detail object.

    Create a task

    POST/tasks

    If new_number is omitted, the next number for the project is assigned (starting at 1).

    Encoding: multipart/form-data

    Required form fields

    FieldTypeDescription
    task_titleRequiredstringTask title.
    aboutRequiredstringDescription.
    project_idRequiredintegerProject database identifier.
    created_byRequiredstringStored as sent.
    due_byRequireddate stringFormat follows iso2.
    iso2RequiredstringDate-format selector.
    timezoneRequiredstringLocal time zone.
    organization_idRequiredintegerUsed for attachment paths.
    project_nameRequiredstringUsed in notifications.
    project_uuidRequiredstringUsed in notification links.

    Optional form fields

    FieldTypeDescription
    new_numberinteger textExplicit task number. Not guaranteed unique.
    intended_forstring (repeat)Recipient email. Repeat the field for each user.
    intended_for_groupsinteger (repeat)Recipient group pk. Repeat the field for each group.
    wf1_emails … wf5_emailsstring (repeat)Workflow user emails for steps 1–5.
    wf1_groups … wf5_groupsinteger (repeat)Workflow group pk values for steps 1–5.
    wf1_complete … wf5_completepresence flagInclude to mark a step complete; omit for incomplete.
    filename0, filename1, …fileDistinct field name per file.
    linked_closeout_tradeintegerCloseout trade identifier.
    meeting_topic_idstringMeeting topic position reference.
    meeting_idConditionalintegerRequired when meeting_topic_id is supplied.
    cURL
    curl --request POST "https://api.jet.build/tasks" \
      -H "Authorization: Token YOUR_API_TOKEN" \
      -H "Accept: application/json" \
      --form-string "task_title=Inspect slab edge" \
      --form-string "about=Verify the slab edge dimension at Grid B." \
      --form-string "project_id=123" \
      --form-string "created_by=Example User" \
      --form-string "due_by=11/05/2026" \
      --form-string "iso2=US" \
      --form-string "timezone=America/New_York" \
      --form-string "organization_id=10" \
      --form-string "project_name=Example Project" \
      --form-string "project_uuid=11111111-1111-4111-8111-111111111111" \
      --form-string "intended_for=manager@example.com" \
      --form-string "wf1_emails=superintendent@example.com" \
      --form "filename0=@./task-detail.pdf"

    Response

    200 OK

    Tasks objects

    Task list item

    Item returned by GET /tasks?project_pk=…

    FieldTypeDescription
    pkintegerDatabase identifier.
    task_idstring (UUID)Task UUID (called uuid in detail).
    titlestringTask title.
    numberintegerTask number.
    due_byDueDateFormatted date.
    is_openbooleanTrue only when stored status is opn.
    statusStatusFrom the task's status method.
    created_bystringStored creator.
    sent_on_localstringCreation display timestamp.
    bicBallInCourt | nullNull when stored status is cmp.
    Example
    {
      "pk": 456,
      "task_id": "44444444-4444-4444-8444-444444444444",
      "title": "Inspect slab edge",
      "number": 12,
      "due_by": { "date": "11/05/2026", "display": "Nov 05, 2026" },
      "is_open": true,
      "status": { "status": "OPEN", "days_overdue": -8 },
      "created_by": "Example User",
      "sent_on_local": "Wed Oct 28, 2026 at 03:30 PM",
      "bic": { "groups": [], "users": ["superintendent@example.com"] }
    }

    Task detail

    Returned by GET /tasks?task_pk=… Omits number, created_by, sent_on_local, is_open, Ball in Court and attachments.

    FieldTypeDescription
    pkstringSubmitted identifier, as a string.
    titlestringTask title.
    uuidstring (UUID)Same value as task_id.
    aboutstringDescription.
    statusstringRaw stored status, e.g. opn.
    due_byDueDateFormatted date.
    tagsanySchema pending confirmation.
    ccdRecipientsDistribution recipients.
    linked_closeout_tradeinteger | emptyCloseout trade id.
    workflowWorkflowStep[]Workflow steps.
    Example
    {
      "pk": "456",
      "title": "Inspect slab edge",
      "uuid": "44444444-4444-4444-8444-444444444444",
      "about": "Verify the slab edge dimension at Grid B.",
      "status": "opn",
      "due_by": { "date": "11/05/2026", "display": "Nov 05, 2026" },
      "tags": "…",
      "ccd": { "groups": [], "users": ["manager@example.com"] },
      "linked_closeout_trade": null,
      "workflow": [{ "groups": [], "users": ["superintendent@example.com"], "complete": false }]
    }

    Task created

    Returned by POST /tasks. status is always the computed OPEN object here.

    FieldTypeDescription
    pkintegerNew database identifier.
    task_idstring (UUID)Task UUID.
    titlestringTitle.
    numberinteger | stringString if you sent new_number.
    due_byDueDateFormatted date.
    statusStatusOPEN with days_overdue.
    created_bystringCreator.
    sent_on_localstringCreation display timestamp.
    linked_closeout_trade_idinteger | nullCloseout trade id.
    ball_in_courtBallInCourtNamed ball_in_court here.
    Example
    {
      "pk": 456,
      "task_id": "44444444-4444-4444-8444-444444444444",
      "title": "Inspect slab edge",
      "number": 12,
      "due_by": { "date": "11/05/2026", "display": "Nov 05, 2026" },
      "status": { "status": "OPEN", "days_overdue": -8 },
      "created_by": "Example User",
      "sent_on_local": "Wed Oct 28, 2026 at 03:30 PM",
      "linked_closeout_trade_id": null,
      "ball_in_court": { "groups": [], "users": ["superintendent@example.com"] }
    }

    Tasks status values

    Stored task status

    The complete list is pending confirmation.

    opn
    Open. is_open is true.
    cmp
    Complete. bic is null.
    OPEN
    Label always returned by the create response.

    Tasks errors

    401 Unauthorized
    Missing or invalid token. Body is null.
    Invalid date
    Silently replaced with the server's current date.

    Pending confirmation: Task update (PUT /tasks) is listed in the guide but its field reference was not included in the supplied document..

    Need identifiers or access for an integration?

    Jet.Build provides API tokens, group ids and registry references for your projects. Request examples are illustrative; confirm behavior against your account before going to production.

    Talk to the Jet.Build team