Your crews' daily logs, reports, photos, hours and change orders, available to AI assistants and to your own code.
Everything is read-only and limited to your company.
ProBlu turns what field crews text into daily logs, field reports, timecards and change orders. There are two ways to use that data outside ProBlu:
AI connector
REST API
For
Claude, Codex, Cursor and other AI assistants
Your own scripts, reports and integrations
Address
https://api.problu.com/mcp
https://api.problu.com/v1
Protocol
Model Context Protocol (streamable HTTP)
HTTPS + JSON
Key
AI connector key
API key
Both are included on every ProBlu plan while the account is active, and both are read-only: nothing can create, change or delete records.
Keys and access
A company admin creates keys in ProBlu under Integrations → AI and API access.
An AI connector key only works with the AI connector, and an API key only works with the REST API. Each key is shown once,
so store it like a password. Send it as Authorization: Bearer pb_live_….
Each key reads one company's data, limited to the kinds of data the admin picks:
Data
Includes
On by default
jobs
Jobs, addresses, status and crew
Yes
daily_logs
Daily logs and their PDFs
Yes
reports
Field reports, shared reports and their PDFs
Yes
photos
Job photos and files
Yes
timecards
Timecard entries and hours
Yes
change_orders
Change orders, amounts and PDFs
Yes
people
Employee names and roles (no phone numbers or emails)
Yes
admin_only_reports
Report types marked Admins only, such as internal walks of a super's job
No
A key stops working when an admin revokes it, when the admin who created it loses admin access, or while the company's plan is paused.
Connect an AI tool
Create an AI connector in ProBlu, then add ProBlu to your tool as a remote MCP server:
Every endpoint is a GET. The full list is in the reference below, and the OpenAPI spec works with code generators and API clients.
IDs, paging and dates
IDs are strings with a type prefix: job_123, dlog_456, frep_78, srep_12, media_901, time_3304, co_55, user_12. Pass them back exactly.
Lists return data and next_cursor. Pass cursor to get the next page and limit (1–100, default 25) to change its size. next_cursor is null on the last page.
Dates such as since, until and a log's date are YYYY-MM-DD in the company's time zone. Timestamps are ISO 8601 with a time zone.
Download links on photos and files expire after an hour. Ask for the record again to get a fresh one.
A list response
{
"data": [
{
"id": "dlog_456",
"job_id": "job_123",
"date": "2026-10-01",
"content": "Framed the north wall…"
}
],
"next_cursor": "eyJrIjoiMjAyNi0xMC0wMSIsImlkIjo0NTZ9"
}
Errors
Errors return an HTTP status and a stable code you can match on:
{
"detail": {
"code": "not_found",
"message": "No daily log with that ID in this company."
}
}
Status
Code
Meaning
401
api_key_required
No key was sent. Send `Authorization: Bearer <key>`.
401
invalid_api_key
The key is wrong, mistyped or revoked.
401
api_key_inactive
The admin who created the key no longer has admin access.
403
wrong_key_type
An AI connector key was used with the REST API, or an API key with /mcp.
More than 120 requests in a minute. Wait for Retry-After seconds.
503
service_unavailable / pdf_unavailable
Try again shortly.
AI connector tools return problems as a tool error the AI can read and correct, instead of an HTTP status.
Rate limits
Each key can make 120 requests a minute. Past that, requests get 429 rate_limited with a Retry-After header in seconds.
Your data
Your records stay in ProBlu. When an AI tool or script reads them with a key, the results go to that tool, and for AI tools to its AI provider under their terms.
Test records, deleted records, storage paths, phone numbers and email addresses are never returned. ProBlu logs every request so admins can see how keys are used.
AI connector tools
The AI connector at https://api.problu.com/mcp offers these tools. An AI tool only sees the ones its key's data allows.
get_account
Which ProBlu company this connection reads, its timezone, and the data the key can see.
list_jobsjobs
List the company's jobs, newest first. Filter by status or by text in the job name, GC or address.
status · Job status, e.g. Active.query · Text to match in name, general contractor or address.limit · Page size (default 25).cursor · next_cursor from the previous call.
get_jobjobs
One job with its address, notes and assigned crew.
job_id required · Job ID, e.g. job_123.
search_daily_logsdaily_logs
Daily logs (what the crew did, manpower, milestones, answers to daily questions), newest date first. Filter by job, date range and text.
job_id · Only this job, e.g. job_123.since · Earliest date, YYYY-MM-DD.until · Latest date, YYYY-MM-DD.query · Text to match in the log.limit · Page size (default 25).cursor · next_cursor from the previous call.
get_daily_logdaily_logs
One daily log in full.
daily_log_id required · Daily log ID, e.g. dlog_456.
list_field_reportsreports
Field reports (inspections, site visits and other company-defined report types), newest first.
job_id · Only this job, e.g. job_123.since · Earliest date, YYYY-MM-DD.until · Latest date, YYYY-MM-DD.query · Text to match in the report.limit · Page size (default 25).cursor · next_cursor from the previous call.
get_field_reportreports
One field report in full.
field_report_id required · Field report ID, e.g. frep_78.
list_shared_reportsreports
Saved shared reports (the date-range packets sent to GCs and owners), with their written summaries.
job_id · Only this job, e.g. job_123.limit · Page size (default 25).cursor · next_cursor from the previous call.
get_shared_reportreports
One saved shared report with its day-by-day contents: each day's daily logs and field reports, plus change orders in the period when the key allows them.
shared_report_id required · Shared report ID, e.g. srep_12.
list_photosphotos
Photos, videos and files on jobs, newest first, with short-lived download links. Filter by job, daily log or field report.
job_id · Only this job, e.g. job_123.daily_log_id · Only media attached to this daily log.field_report_id · Only media attached to this field report.limit · Page size (default 25).cursor · next_cursor from the previous call.
get_photophotos
Show one photo as an image (a 512px preview) with its details.
photo_id required · Photo ID, e.g. media_901.
list_time_entriestimecards
Timecard entries with worked minutes, newest work date first. Filter by job, employee and date range.
job_id · Only this job, e.g. job_123.employee_id · Only this person, e.g. user_12.since · Earliest date, YYYY-MM-DD.until · Latest date, YYYY-MM-DD.limit · Page size (default 25).cursor · next_cursor from the previous call.
list_change_orderschange_orders
Change orders with status and total amount, newest first. Drafts are hidden unless status is Draft.
job_id · Only this job, e.g. job_123.status · Status, e.g. Executed, Unexecuted, Incomplete, Cancelled or Draft.limit · Page size (default 25).cursor · next_cursor from the previous call.
get_change_orderchange_orders
One change order with its priced line items.
change_order_id required · Change order ID, e.g. co_55.
list_peoplepeople
The company's people with their role (admin, office or field). No phone numbers or emails.
include_inactive · Include deactivated people.
search
Search jobs, daily logs and field reports by text. Returns ids to pass to fetch.
query required · What to look for.
fetch
Get the full text of a job, daily log or field report by an id from search.
id required · An id from search, e.g. dlog_456.
Account
GET/v1/me
The company and key in use
Returns the company this key reads, its timezone, and the kinds of data the key can see. Useful to check a key works.
Response fields and example
Field
Type
Description
company_name
string
The company this key reads.
company_timezone
string or null
key_name
string or null
The name the admin gave the key.
key_prefix
string
The first characters of the key, for recognizing it.
One job with its address, notes and currently assigned crew.
Parameter
In
Description
job_id required
path
The record ID.
Response fields and example
Field
Type
Description
id
string
Job ID, for example job_123.
name
string or null
Job name.
status
string or null
Job status as set in ProBlu, for example Active or Complete.
general_contractor
string or null
General contractor name.
address
object
street
string or null
city
string or null
state
string or null
zip
string or null
notes
string or null
Job notes shared with the crew.
created_at
date-time or null
When the job was created.
crew
array of objects
People currently assigned to the job.
id
string
Person ID, for example user_12.
name
string or null
{
"id": "job_123",
"name": "Green Bank Remodel",
"status": "Active",
"general_contractor": "Summit Builders",
"address": {
"street": "410 Main St",
"city": "Denver",
"state": "CO",
"zip": "80202"
},
"notes": "Gate code 4410. Park on 5th.",
"created_at": "2026-10-01T15:04:05Z",
"crew": [
{
"id": "user_12",
"name": "Green Bank Remodel"
}
]
}
Daily logs
GET/v1/daily-logsdaily_logs
List daily logs
Newest log date first. Each log has what the crew wrote, structured work entries (work, people, hours), milestones and answers to the company's daily questions.
Parameter
In
Description
job_id
query
Only this job, for example job_123.
since
query
Earliest date, YYYY-MM-DD.
until
query
Latest date, YYYY-MM-DD.
q
query
Match text in the log.
limit
query
Page size, 1-100 (default 25).
cursor
query
`next_cursor` from the previous page.
Response fields and example
Field
Type
Description
data
array of objects
id
string
Daily log ID, for example dlog_456.
job_id
string
Job the log belongs to.
job_name
string or null
date
date
The work day the log covers, in the company's time zone.
author
object or null
Who submitted the log.
id
string
Person ID, for example user_12.
name
string or null
content
string or null
The written daily log.
work_entries
array of objects
Structured work, manpower and hours.
work
string or null
What was worked on.
people
string or null
Names or a headcount, as recorded.
total_hours
number or null
Total crew hours for this work, when stated.
notes
string or null
Extra notes on this work.
milestones
array of strings
Milestones reached that day.
questions
array of objects
Answers to the company's daily questions.
question
string or null
One of the company's daily questions.
answer
string or null
The answer recorded for the day.
pdf_url
string
REST path to the PDF.
created_at
date-time
updated_at
date-time
Last edit.
next_cursor
string or null
Pass as `cursor` to get the next page; null when done.
{
"data": [
{
"id": "dlog_456",
"job_id": "job_123",
"job_name": "Green Bank Remodel",
"date": "2026-10-01",
"author": {
"id": "user_12",
"name": "Green Bank Remodel"
},
"content": "Framed the north wall and set two headers.",
"work_entries": [
{}
],
"milestones": [
"Walls sheathed"
],
"questions": [
{}
],
"pdf_url": "/v1/daily-logs/dlog_456/pdf",
"created_at": "2026-10-01T15:04:05Z",
"updated_at": "2026-10-01T15:04:05Z"
}
],
"next_cursor": "eyJrIjoiMjAyNi0xMC0wMSIsImlkIjo0NTZ9"
}
GET/v1/daily-logs/{daily_log_id}daily_logs
Get a daily log
One daily log in full.
Parameter
In
Description
daily_log_id required
path
The record ID.
Response fields and example
Field
Type
Description
id
string
Daily log ID, for example dlog_456.
job_id
string
Job the log belongs to.
job_name
string or null
date
date
The work day the log covers, in the company's time zone.
author
object or null
Who submitted the log.
id
string
Person ID, for example user_12.
name
string or null
content
string or null
The written daily log.
work_entries
array of objects
Structured work, manpower and hours.
work
string or null
What was worked on.
people
string or null
Names or a headcount, as recorded.
total_hours
number or null
Total crew hours for this work, when stated.
notes
string or null
Extra notes on this work.
milestones
array of strings
Milestones reached that day.
questions
array of objects
Answers to the company's daily questions.
question
string or null
One of the company's daily questions.
answer
string or null
The answer recorded for the day.
pdf_url
string
REST path to the PDF.
created_at
date-time
updated_at
date-time
Last edit.
{
"id": "dlog_456",
"job_id": "job_123",
"job_name": "Green Bank Remodel",
"date": "2026-10-01",
"author": {
"id": "user_12",
"name": "Green Bank Remodel"
},
"content": "Framed the north wall and set two headers.",
"work_entries": [
{
"work": "Framing",
"people": "4",
"total_hours": 8,
"notes": "Gate code 4410. Park on 5th."
}
],
"milestones": [
"Walls sheathed"
],
"questions": [
{
"question": "Any safety issues?",
"answer": "None reported"
}
],
"pdf_url": "/v1/daily-logs/dlog_456/pdf",
"created_at": "2026-10-01T15:04:05Z",
"updated_at": "2026-10-01T15:04:05Z"
}
GET/v1/daily-logs/{daily_log_id}/pdfdaily_logs
Download a daily log PDF
The same branded PDF ProBlu emails, with photos.
Parameter
In
Description
daily_log_id required
path
The record ID.
Returns application/pdf.
Field reports
GET/v1/field-reportsreports
List field reports
Inspections, site walks and other report types the company defines. Admin-only report types need the admin_only_reports scope.
Parameter
In
Description
job_id
query
Only this job, for example job_123.
since
query
Earliest date, YYYY-MM-DD.
until
query
Latest date, YYYY-MM-DD.
q
query
Match text in the report.
limit
query
Page size, 1-100 (default 25).
cursor
query
`next_cursor` from the previous page.
Response fields and example
Field
Type
Description
data
array of objects
id
string
Field report ID, for example frep_78.
job_id
string
job_name
string or null
report_type
string or null
The company-defined report type, for example Site Walk.
date
date
The day the report covers.
author
object or null
id
string
Person ID, for example user_12.
name
string or null
content
string
The written report.
pdf_url
string
REST path to the PDF.
created_at
date-time
updated_at
date-time
next_cursor
string or null
Pass as `cursor` to get the next page; null when done.
{
"data": [
{
"id": "frep_78",
"job_id": "job_123",
"job_name": "Green Bank Remodel",
"report_type": "Site Walk",
"date": "2026-10-01",
"author": {
"id": "user_12",
"name": "Green Bank Remodel"
},
"content": "Framed the north wall and set two headers.",
"pdf_url": "/v1/daily-logs/dlog_456/pdf",
"created_at": "2026-10-01T15:04:05Z",
"updated_at": "2026-10-01T15:04:05Z"
}
],
"next_cursor": "eyJrIjoiMjAyNi0xMC0wMSIsImlkIjo0NTZ9"
}
GET/v1/field-reports/{field_report_id}reports
Get a field report
One field report in full.
Parameter
In
Description
field_report_id required
path
The record ID.
Response fields and example
Field
Type
Description
id
string
Field report ID, for example frep_78.
job_id
string
job_name
string or null
report_type
string or null
The company-defined report type, for example Site Walk.
date
date
The day the report covers.
author
object or null
id
string
Person ID, for example user_12.
name
string or null
content
string
The written report.
pdf_url
string
REST path to the PDF.
created_at
date-time
updated_at
date-time
{
"id": "frep_78",
"job_id": "job_123",
"job_name": "Green Bank Remodel",
"report_type": "Site Walk",
"date": "2026-10-01",
"author": {
"id": "user_12",
"name": "Green Bank Remodel"
},
"content": "Framed the north wall and set two headers.",
"pdf_url": "/v1/daily-logs/dlog_456/pdf",
"created_at": "2026-10-01T15:04:05Z",
"updated_at": "2026-10-01T15:04:05Z"
}
GET/v1/field-reports/{field_report_id}/pdfreports
Download a field report PDF
The branded PDF with photos.
Parameter
In
Description
field_report_id required
path
The record ID.
Returns application/pdf.
Shared reports
GET/v1/shared-reportsreports
List shared reports
Saved date-range packets a company shares with GCs and owners, with their written summaries.
Parameter
In
Description
job_id
query
Only this job, for example job_123.
limit
query
Page size, 1-100 (default 25).
cursor
query
`next_cursor` from the previous page.
Response fields and example
Field
Type
Description
data
array of objects
id
string
Shared report ID, for example srep_12.
job_id
string
job_name
string or null
title
string or null
start_date
date
First day covered.
end_date
date
Last day covered.
summary
string or null
Saved written summary, when one was generated.
created_at
date-time
next_cursor
string or null
Pass as `cursor` to get the next page; null when done.
{
"data": [
{
"id": "srep_12",
"job_id": "job_123",
"job_name": "Green Bank Remodel",
"title": "Last week on Green Bank",
"start_date": "2026-10-01",
"end_date": "2026-10-01",
"summary": "Framing and sheathing finished; trusses started.",
"created_at": "2026-10-01T15:04:05Z"
}
],
"next_cursor": "eyJrIjoiMjAyNi0xMC0wMSIsImlkIjo0NTZ9"
}
GET/v1/shared-reports/{shared_report_id}reports
Get a shared report
One shared report with its day-by-day contents (daily logs and field reports), plus change orders in the period when the key can read them.
Parameter
In
Description
shared_report_id required
path
The record ID.
Response fields and example
Field
Type
Description
id
string
Shared report ID, for example srep_12.
job_id
string
job_name
string or null
title
string or null
start_date
date
First day covered.
end_date
date
Last day covered.
summary
string or null
Saved written summary, when one was generated.
created_at
date-time
days
array of objects
Day-by-day contents, assembled live from the records like the Shared Reports page.