Objects
Field names are snake_case. Timestamps are ISO 8601 in UTC. A field marked optional is left out of the response when it does not apply; every other field is always present, with null where there is no value. Each description says what the field is and how to render it. Fields are only ever added within v1; see the changelog.
Business
Section titled “Business”The business the jobs belong to. Returned on every response as business, so a single fetch has everything a page needs.
| Field | Type | Description |
|---|---|---|
slug |
string |
The business’s address segment in every Publish API URL. |
name |
string |
The business’s display name. |
phone |
string | null |
The phone number to show and to use in a tel: link. E.164 where available. |
primary_service_area |
string | null |
The business’s main service area as free text, e.g. "North Atlanta". |
primary_vertical |
string |
The business’s trade as a lowercase id, e.g. "pressure-washing". "other" for a trade not on the list; see industry_label. |
industry_label |
string | null |
The business’s own words for its trade. Set only when primary_vertical is "other". Display industry_label ?? primary_vertical. |
canonical_domain |
string | null |
The website the pages live on, e.g. "https://yourcompany.com", with no trailing slash. null until the website connection is set up. |
jobs_base_path |
string |
The path the job pages live under on canonical_domain. Default "/work". |
service_path_pattern |
string |
Path pattern for the business’s own service pages, e.g. "/services/{slug}". {slug} appears exactly once. |
location_path_pattern |
string |
Path pattern for the business’s own service-area pages, e.g. "/service-areas/{slug}". {slug} appears exactly once. |
category_index_paths |
{ by_service: string; by_location: string; } |
Path patterns for the job-index pages grouped by service (by_service, e.g. "/work/services/{slug}") and by location (by_location, e.g. "/work/locations/{slug}"). |
branding |
BusinessBranding | null |
Logo, colours and footer links. null until the business has completed the branding step; render a plain default in that case. |
license_number |
string | null |
The trade or contractor licence as the business entered it, e.g. "GA GC-12345". Show it as a License # line. |
cities_served |
string[] | null |
Cities the business lists as served, in the business’s order. Empty or null when none are listed. |
public_face |
PublicBusinessPublicFace | null |
The named person credited on the pages. null when the business has not set one. |
booking_url |
string | null |
The online-booking link the business set. null when none. |
cta_kind |
"call" | "book" |
Which primary button to render: "call" (a tel: link to phone) or "book" (a link to booking_url). Treat "book" as "call" when booking_url is null. |
cta_label |
string | null |
Custom text for the primary button, e.g. "Get a free estimate". null means use your own default. |
Public face
Section titled “Public face”The person credited as the author of the pages, in business.public_face.
| Field | Type | Description |
|---|---|---|
name |
string |
Display name, e.g. "Sam Carter". |
title |
string | null |
Role line, e.g. "Owner". null means use a default label. |
bio |
string | null |
A short first-person bio for an “About” block. null when none has been written. |
sameAs |
string[] |
Profile URLs for this person (LinkedIn, directories). Empty when none are set. Suitable for a Person.sameAs array in JSON-LD. |
Branding
Section titled “Branding”The configurable parts of the brand shell, in business.branding.
| Field | Type | Description |
|---|---|---|
logo_url |
string | null |
Absolute, durable URL of the logo. null when none is uploaded; show the business name as text instead. |
primary_color |
string |
CSS colour for dark surfaces such as the header, e.g. "#0e2538". Safe to use directly in background-color. |
accent_color |
string |
CSS colour for buttons and links, e.g. "#0a58ca". Safe to use directly in color or background-color. |
footer_link_scheme |
"primary_only" | "primary_and_socials" | "minimal" |
Which footer links the business chose: "primary_only" (just primary_links), "primary_and_socials" (plus the socials row), or "minimal" (neither). |
primary_links |
{ label: string; url: string; }[] |
Links to the business’s own pages for the footer, as { label, url }, in the business’s order. |
socials |
{ facebook?: string; instagram?: string; tiktok?: string; google?: string; yelp?: string; linkedin?: string; } |
Profile URLs keyed by platform: facebook, instagram, tiktok, google, yelp, linkedin. Every key is optional; skip empty values. |
A published job page. Only published jobs are ever returned. Some fields are filled only by Get a job; the list endpoint returns them empty or null, as noted.
| Field | Type | Description |
|---|---|---|
slug |
string |
The job’s address segment, unique within the business. |
headline |
string |
The page title. Up to 120 characters. |
meta_description |
string |
Up to 160 characters, ready for <meta name="description">. |
body_markdown |
string |
The write-up as GitHub-flavoured Markdown. Always present. |
body_html |
string | null |
The write-up as sanitised HTML with internal links resolved. null when not available; render body_markdown instead. |
vertical |
string |
The trade the job belongs to, as a lowercase id. |
service_type |
string |
The service as a lowercase slug, e.g. "house-washing". Use it to build category URLs. |
service_type_display |
string |
The service for display, e.g. "House Washing". |
service_city |
string |
The city as a lowercase slug, e.g. "marietta". |
service_city_display |
string |
The city for display, e.g. "Marietta". |
service_state |
string |
Two-letter US state code, e.g. "GA". |
service_area_slug |
string | null |
City and state as one slug, e.g. "canton-ga", for location_path_pattern. null on some older jobs; build it from service_city and service_state then. |
completed_at |
string |
When the work was done. |
published_at |
string |
When the page went live. |
updated_at |
string |
When the page last changed. Use it for cache busting. |
media |
MediaItem[] |
The photos, in display order. Index 0 is the main photo. May be empty. |
og_image_url |
string | null |
Absolute URL of the Open Graph image. null when the job has no photos. |
schema_org |
Record<string, unknown> | null |
A JSON-LD object to place verbatim in a <script type="application/ld+json"> tag. null when none is available. |
noindex |
boolean |
true when the page should carry <meta name="robots" content="noindex">. |
canonical_slug |
string | null |
The slug of an earlier page for the same property and service, when this page is a later visit. Informational: link the two if you like, but do not use it as a rel="canonical" target. Detail endpoint only; null otherwise. |
gallery_order |
"curated" | "derived" |
"curated" when someone at the business arranged the photos by hand (render media exactly as given); "derived" when the order is the default (you may lead with before/after pairs). |
source_line_items |
PublicLineItem[] |
The line items from the scheduling tool, in order, never with prices. Detail endpoint only; [] on list responses. |
work_duration_minutes |
number | null |
Minutes the crew was on site, when known. null otherwise. |
what_we_found |
string | null |
A short summary of what the crew found, when the write-up supports one. Detail endpoint only; null otherwise. |
what_we_did |
string | null |
A short summary of the work done, when the write-up supports one. Detail endpoint only; null otherwise. |
judgment_calls |
string | null |
A short note on decisions made on site, when the write-up supports one. Detail endpoint only; null otherwise. |
what_we_recommend |
string | null |
A short recommendation to the customer, when the write-up supports one. Detail endpoint only; null otherwise. |
related_jobs |
RelatedJob[] |
Up to six related jobs to show beneath the page. May be empty. |
money_page_service_url |
string | null |
Absolute URL of the business’s own service page for this job’s service, built from service_path_pattern. null when the business has no website connection or the page does not apply. |
money_page_area_url |
string | null |
Absolute URL of the business’s own service-area page for this job’s city, built from location_path_pattern. null on the same terms as money_page_service_url. |
project_facts |
ProjectFacts |
Structured facts for a “Project at a glance” block. |
reviews |
PublicReview[] |
Customer reviews tied to this job, newest first. Empty when there are none. |
Line item
Section titled “Line item”One entry in job.source_line_items.
| Field | Type | Description |
|---|---|---|
name |
string |
What was done, as the scheduling tool recorded it. |
qty |
number | null |
Quantity, when recorded. null otherwise. |
unit |
string | null |
Unit for qty, when recorded. null otherwise. |
kind |
"labor" | "materials" | "other" |
"labor", "materials", or "other" when the source did not say. |
Media item
Section titled “Media item”One photo in job.media.
| Field | Type | Description |
|---|---|---|
url |
string |
Absolute, durable URL. Never an expiring link. |
width |
number |
Pixel width of the image at url. |
height |
number |
Pixel height of the image at url. |
alt |
string |
Alt text. Always non-empty. |
kind |
"before" | "after" | "process" | "hero" |
"before", "after", "process", or "hero". |
caption |
string (optional) |
A caption to show beneath the photo. Left out when there is none; do not use alt as a caption. |
pair_id |
string | null |
Shared by a before and an after photo of the same spot. Treat two photos as a pair only when both carry those kinds and the same pair_id; a photo may carry a pair_id whose partner is not in media. null when the photo was never paired. |
variantVersion |
number |
Which set of resized variants exists for this photo. 0 means JPEG only; 1 or higher means WebP variants are also available. |
Related job
Section titled “Related job”A card in job.related_jobs. Enough to render a card without another request.
| Field | Type | Description |
|---|---|---|
slug |
string |
The related job’s address segment. |
headline |
string |
The related job’s title. |
service_type_display |
string |
Its service, for display. |
service_city_display |
string |
Its city, for display. |
hero_url |
string | null |
URL of its main photo. null when it has none. |
tier |
"same_service_and_city" | "same_service" | "same_city" (optional) |
Why it is related: "same_service_and_city", "same_service", or "same_city". When absent, group the card under a neutral “Nearby work” heading. |
Review
Section titled “Review”A customer review in job.reviews. Always a real review tied to that job.
| Field | Type | Description |
|---|---|---|
rating |
number | null |
Stars, 1 to 5. null when the review had no rating. |
reviewer_name |
string | null |
The reviewer’s public display name, e.g. "John S.". null when absent. |
snippet |
string | null |
The review text. |
posted_at |
string | null |
When the review was posted. null when unknown. |
Project facts
Section titled “Project facts”Structured facts about one job, in job.project_facts.
| Field | Type | Description |
|---|---|---|
services |
string[] |
The services on this job, for display. Usually one. |
surfaces |
string[] |
Surfaces worked on, e.g. ["Vinyl siding", "Concrete"]. May be empty. |
conditions |
string[] |
Conditions found, e.g. ["Algae", "Mildew"]. May be empty. |
property_type |
"residential" | "commercial" | null |
"residential", "commercial", or null when unknown. |
photo_count |
number |
How many photos the job has. |
before_after_pair_count |
number |
How many before/after pairs the job has. |
Jobs aggregates
Section titled “Jobs aggregates”Counts across all of a business’s published jobs, not just the current page. Returned as aggregates on list and detail responses; null when the caller opted out with ?aggregates=false or the counts were temporarily unavailable.
| Field | Type | Description |
|---|---|---|
total_jobs |
number |
Number of published jobs. |
most_recent_completed_at |
string | null |
The newest completed_at across all published jobs. null when there are none. |
services |
JobCluster[] |
One entry per service with published jobs. |
cities |
JobCluster[] |
One entry per city with published jobs. |
Job cluster
Section titled “Job cluster”One service or city in aggregates.services or aggregates.cities.
| Field | Type | Description |
|---|---|---|
slug |
string |
The service or city slug, matching job.service_type or job.service_city. |
display |
string |
The display name. |
count |
number |
Number of published jobs in this group. |
most_recent_completed_at |
string | null |
The newest completed_at in this group. null when none. |
Pagination
Section titled “Pagination”Returned as pagination on list responses. See Pagination.
| Field | Type | Description |
|---|---|---|
next_cursor |
string | null |
Opaque token for the next page. Pass it back unchanged as ?cursor=. null on the last page. |
has_more |
boolean |
true when another page exists. |
List jobs response
Section titled “List jobs response”The body of List jobs.
| Field | Type | Description |
|---|---|---|
business |
PublicBusiness |
The business. |
jobs |
PublicJob[] |
The jobs on this page, newest completed first. |
pagination |
Pagination |
Cursor for the next page. |
aggregates |
JobsAggregates | null |
Counts across all published jobs, or null. |
Job detail response
Section titled “Job detail response”The body of Get a job.
| Field | Type | Description |
|---|---|---|
business |
PublicBusiness |
The business. |
job |
PublicJob |
The job, with every detail-only field filled. |
aggregates |
JobsAggregates | null |
Counts across all published jobs, or null. |
The body of every non-2xx response. See Errors.
| Field | Type | Description |
|---|---|---|
error |
string |
A stable snake_case code. |
message |
string (optional) |
Reserved. Not sent today. |
details |
{ [x: string]: unknown; } (optional) |
Reserved. Not sent today. |
Webhook payload
Section titled “Webhook payload”The body of every webhook delivery. It says what changed, not what the new state is: fetch the job to get current data. See Webhooks.
| Field | Type | Description |
|---|---|---|
event |
"job.published" | "job.updated" | "job.unpublished" | "job.deleted" |
"job.published", "job.updated", "job.unpublished", or "job.deleted". |
occurred_at |
string |
When the change happened. |
business |
{ slug: string; } |
{ slug } of the business. |
job |
{ slug: string; service_type?: string; service_city?: string; sibling_slugs?: string[]; sibling_categories?: { service_type?: string; service_city?: string; }[]; } |
{ slug } plus, when the job has them, service_type and service_city (slugs, for invalidating category pages), sibling_slugs (other pages that link to this one and should be refreshed with it) and sibling_categories (category pages that changed alongside it). On job.unpublished and job.deleted these are the only way to learn which category pages the job was on. |
delivery |
{ id: string; attempt: number; } |
{ id, attempt }: a UUID for this delivery, echoed in the X-SimplifyLocal-Delivery header. Retries resend the same body, so attempt is always 1 today; use id to detect duplicates. |