api.jobs.manage.manage permission unless noted. State-mutating requests (POST, PUT, DELETE) must include a csrf_token field — obtain one from GET /api/security/csrf-token.
Job fields containing personal contact information (
private_contact_name, private_contact_email, access_details) are encrypted at rest using XSalsa20-Poly1305 and are transparently decrypted in API responses.Jobs
List and retrieve jobs
- List jobs
- Get single job
GET /api/jobs/manage?action=listReturns a paginated list of jobs. You can narrow results with any combination of filters.Required permission: api.jobs.manage.listMust be
list.Full-text search across job title, reference, and description.
Filter by job status ID.
Filter by priority ID.
Filter by assigned agent.
Filter by assigned contractor.
Filter by the staff member who created the job.
Set to
true to return only jobs that have photos attached.Set to
true to return only jobs that have documents attached.Maximum records to return (max 200).
Number of records to skip.
Create a job
POST /api/jobs/manage
Creates a new maintenance job. On success returns HTTP 201 with the new job ID, UUID, and reference.
Required permission: api.jobs.manage.manage
Must be
create.Short descriptive title for the job.
Full description of the works required.
Priority level ID. Retrieve available values from
GET /api/jobs/priorities?action=list.Initial job status ID. Retrieve available values from
GET /api/jobs/statuses?action=list.Job type category ID. Retrieve available values from
GET /api/jobs/types?action=list.Property address ID.
ID of the agent to assign.
ID of the contractor to assign.
Array of tenant IDs associated with the job.
Total client-facing budget (inclusive of VAT).
Amount payable to the contractor.
VAT rate to apply. Defaults to the platform VAT rate configured by your administrator (default 20%).
Scheduled start date (
YYYY-MM-DD).Scheduled completion date (
YYYY-MM-DD).Site access instructions. Encrypted at rest.
Works order reference number.
Invoice number to pre-populate.
Private contact name. Encrypted at rest.
Private contact email. Encrypted at rest.
CSRF token from
GET /api/security/csrf-token.Update a job
POST /api/jobs/manage with action=update
Update one or more fields on an existing job. Only the fields you include in the request body are changed.
Must be
update.UUID of the job to update.
CSRF token.
Delete a job
POST /api/jobs/manage with action=delete
Permanently removes a job and all associated data (case notes, photos, documents).
Must be
delete.UUID of the job to delete.
CSRF token.
Case Notes
Case notes support rich text, email threading, and file attachments. Note text is encrypted at rest.List case notes
GET /api/jobs/case-notes?action=list&job_uuid=<uuid>
Required permission: api.jobs.case_notes.manage
Must be
list.UUID of the parent job.
Create a case note
POST /api/jobs/case-notes
UUID of the parent job.
Note content. Accepts plain text or HTML from rich-text editors.
When
true, sends the note as an email to relevant parties. Replies to that email will be threaded back to this note.CSRF token.
Update a case note
POST /api/jobs/case-notes with action=update — Edit the note text or toggle the pinned state.
Delete a case note
POST /api/jobs/case-notes with action=delete — Remove a case note by UUID.
Photos
List photos
GET /api/jobs/photos?job_id=<id>
Required permission: api.jobs.photos.manage
Returns photo metadata grouped by type (before, during, after, other).
Upload a photo
POST /api/jobs/photos with action=upload
Upload via multipart/form-data. Photos are auto-compressed on ingest.
Must be
upload.ID of the job.
Image or video file. Accepted formats: JPEG, PNG, MP4. Maximum 20 MB per file.
CSRF token.
Delete a photo
DELETE /api/jobs/photos — Send the photo ID as a JSON body {"id": <id>}.
Documents
List documents
GET /api/jobs/documents?action=list&job_id=<id>
Required permission: api.jobs.documents.manage
Returns document metadata. Download a document with action=download&uuid=<uuid>.
Upload a document
POST /api/jobs/documents with action=upload
Must be
upload.ID of the job.
File type category ID.
Document file. Accepted formats: PDF, DOCX, JPEG, PNG. Maximum 20 MB.
CSRF token.
Delete a document
DELETE /api/jobs/documents — Send the document ID as a JSON body {"document_id": <id>}.
Recalls
A recall reopens a completed job, recording the reason and creating a full audit trail.Create a recall
POST /api/jobs/recall
Required permission: api.jobs.recall.manage
UUID of the job to mark as recalled.
Explanation of why the recall is being raised.
Set to
1 to mark as recalled, 0 to complete/clear a recall.When completing a recall (
is_recall=0): standard to complete, cancel to cancel.CSRF token.
Amendments
The amendment flow lets contractors or agents propose changes to job fields (e.g. budget) which must be accepted or rejected by a manager.List amendment requests
GET /api/jobs/amend-request
Returns pending or historical amendment requests. Filter by job, status, or retrieve a single request by UUID.
Required permission: api.jobs.amend_request.manage
Filter requests to a specific job UUID.
Filter by status:
pending, approved, or rejected.Retrieve a single amendment request by its UUID.
Submit an amendment request
POST /api/jobs/amend-request
Creates a new amendment request for a job field.
Required permission: api.jobs.amend_request.manageRequires CSRF token.
UUID of the job.
The job field being proposed for change (e.g.
contractor_budget). Use GET /api/jobs/amendable-fields to discover eligible fields.The proposed new value.
Justification for the change.
CSRF token from
GET /api/security/csrf-token.Approve or reject an amendment request
PATCH /api/jobs/amend-request
Approves or rejects a pending amendment request. Only users with management authority can action requests.
Required permission: api.jobs.amend_request.manageRequires CSRF token.
UUID of the amendment request to action.
New status:
approved or rejected.CSRF token from
GET /api/security/csrf-token.SLA Status
Get SLA status
GET /api/jobs/sla-status
Returns SLA compliance data and breach detection for jobs. Response includes whether each job is within its SLA window, overdue, or breached.
Required permission: api.jobs.manage.manage
Approval Gate
The approval gate system requires management sign-off before certain jobs can progress to the next status.Approve or reject a gate
POST /api/jobs/approval-gate
Required permission: api.jobs.manage.manage
UUID of the job at the approval gate.
approve or reject.Optional notes to attach to the decision.
CSRF token.
Reference Endpoints
These read-only endpoints return lookup data for populating form dropdowns.| Endpoint | Description |
|---|---|
GET /api/jobs/statuses?action=list | All job status options |
GET /api/jobs/types?action=list | All job type categories |
GET /api/jobs/priorities?action=list | All priority levels |
GET /api/jobs/payment-statuses?action=list | Payment status options |
GET /api/jobs/time-ranges?action=list | Available contractor time slots |
GET /api/jobs/addresses?action=list | Searchable property addresses |
Pin / Unpin
Toggle job pin
POST /api/jobs/toggle-pin
Toggles the pinned state of a job for the authenticated user. Pinned jobs appear in the Pinned Jobs dashboard widget. Each user maintains their own independent pin list.
Required permission: api.jobs.toggle_pin.manage
UUID of the job to pin or unpin.
is_pinned will be false and the message will be "Job unpinned from your dashboard".
Remedials
Remedial jobs are linked follow-on jobs created when the original job requires additional work after completion. The remedials API manages those relationships.List remedial links
GET /api/jobs/remedials?action=list&job_uuid=<uuid>
Returns all jobs linked as remedials to the specified job.
Required permission: api.jobs.remedials.manage
Must be
list.UUID of the parent job.
Link a remedial job
POST /api/jobs/remedials with action=link
Creates a remedial relationship between an existing job and a target job.
Required permission: api.jobs.remedials.manageRequires CSRF token.
Must be
link.UUID of the parent job.
UUID of the job to link as a remedial.
CSRF token from
GET /api/security/csrf-token.Unlink a remedial job
POST /api/jobs/remedials with action=unlink
Removes the remedial relationship between two jobs. The jobs themselves are not deleted.
Required permission: api.jobs.remedials.manageRequires CSRF token.
Must be
unlink.UUID of the job to unlink from its remedial parent.
CSRF token.
Mark Recall Completed
Complete a recalled job
POST /api/jobs/mark-recall-completed
Marks a job that is currently in recall status as completed. This closes the recall cycle and records a completion timestamp.
Required permission: api.jobs.mark_recall_completed.manage
UUID of the recalled job to mark as completed. Send as a JSON body.
Amendable Fields
Get amendable fields
GET /api/jobs/amendable-fields?job_uuid=<uuid>
Returns the list of fields that can be proposed for amendment on a specific job, along with their current values and available options. The response is role-aware — contractors see a different subset of fields than staff.
Required permission: api.jobs.amendable_fields.manage
UUID of the job to retrieve amendable fields for.
Video Variants
Get video variants for a job photo
GET /api/jobs/video-variants?uuid=<uuid>
Returns available resolution variants for adaptive video playback for a specific job photo or video file. Use this to build quality-selection controls in video players.
Required permission: api.jobs.photos.view
UUID of the job photo or video record to retrieve variants for.
Variants are only available for video files that have been processed. If
variants is an empty array the original file is the only available source.