Work with this as data
Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/workwing-io:workwing-io-assignments-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
OpenAPI Specification
openapi: 3.2.0
info:
title: WorkWing Assignments API
description: 'REST API for WorkWing field service management. Designed as an **integration point** for CRM, ERP, and dispatch systems. Admin configuration (webhooks, roles, job types, integrations) is managed via the web dashboard. Every resource is documented under its own section in the sidebar. ## Authentication
Send your API key as a bearer token on every request:
```
Authorization: Bearer ww_sk_live_. ```
### Scopes
An API key carries a list of `action:resource` scopes. Every operation publishes the ones it requires as `x-required-scopes`, an array on the operation object; a key must hold all of them, or the wildcard scope `*`, and one that does not is refused with `403 E_AP_1102`. The two operations that declare `security: []` need no key at all: the health check, and the integration callback, which authenticates with the signed token in its own path. ## Querying collections
List endpoints (jobs, customers, resources, and so on) accept query parameters for filtering, sorting, field selection, and pagination:
- `?status=eq.T_PENDING` - filter by exact match
- `?priority=in.(T_HIGH,T_URGENT)` - match any of several values
- `?created_at=gte.2024-01-01` - range comparisons (`gt`, `gte`, `lt`, `lte`)
- `?select=id,status,customer:customers(name)` - choose columns and embed related records. Only the resources listed here, the assignments and users they reference, and the foreign keys between them can be embedded; anything else is refused with `E_AP_6003`
- `?order=created_at.desc` - sort (append `.asc` / `.desc`)
- `?limit=25&offset=50` - paginate (maximum 1000 rows per page)
### Columns not available over the API
Some columns are never returned: `tenant_id` on every resource (a key is bound to one tenant), `internal_notes` on jobs (staff-only; it can be set with `PATCH`, and a job''s note timeline is at `GET /v1/jobs/{jobId}/notes`), and the raw PostGIS geography columns `customers.location`, `locations.location` and `resources.current_location`. Read a position from `latitude`/`longitude` on locations and `current_latitude`/`current_longitude` on resources instead. `select=*`, at the top level or inside an embed, returns every other column. Naming one of these columns in `select`, a filter or `order` is refused with `E_AP_6003`. To read, update or delete one record, address it by id: `GET`, `PATCH` or `DELETE /v1/jobs/{jobId}` (likewise customers, resources and locations). `PATCH` and `DELETE` on a collection change every row matching its filters, e.g. `PATCH /v1/jobs?status=eq.T_PENDING`; they are listed under Workflows. ### Counting and paging
Send `Prefer: count=exact` on a list request to get the total row count back in the `Content-Range` response header (`0-24/312`). `count=planned` and `count=estimated` are cheaper approximations for large tables. ## Idempotency
**Guarantee.** Within 24 hours, a write sent with a given `Idempotency-Key` is applied at most once. If you did not receive a response, retrying with the same key and the same request is always safe. **Core rule.** A key is consumed only when the write is actually applied. The key and the write commit in the same database transaction, so they succeed or fail together. Every write request (`POST`, `PATCH`, `PUT`, `DELETE`) must send an `Idempotency-Key` header. | Situation | Response | Write applied?'
version: 1.0.0
servers:
- url: https://api.workwing.io
description: Production
security:
- bearerAuth: []
tags:
- name: Assignments
description: Assigning resources to jobs
paths:
/v1/assignments/{assignmentId}:
patch:
operationId: updateAssignment
summary: Update assignment status
tags:
- Assignments
description: Update the status of a job assignment
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- status
properties:
status:
type: string
enum:
- T_ASSIGNED
- T_ACKNOWLEDGED
- T_EN_ROUTE
- T_ON_SITE
- T_COMPLETED
- T_FAILED
parameters:
- schema:
type: string
format: uuid
in: path
name: assignmentId
required: true
- $ref: '#/components/parameters/IdempotencyKey'
security:
- bearerAuth: []
x-required-scopes:
- update:jobs
responses:
'200':
description: The updated assignment
content:
application/json:
schema:
description: The updated assignment
type: object
required:
- data
- meta
properties:
data:
type: object
required:
- id
- job_id
- parent_job_id
- resource_id
- user_id
- customer_id
- status
- assigned_at
- assigned_by
- assigned_by_system
- acknowledged_at
- en_route_at
- arrived_at
- notes
- route_position
- estimated_travel_duration
- estimated_travel_distance
- travel_eta
- travel_estimated_at
- departure_latitude
- departure_longitude
- sync_expired_at
- created_at
- updated_at
properties:
id:
type: string
format: uuid
job_id:
type: string
format: uuid
parent_job_id:
type:
- string
- 'null'
format: uuid
description: The project the job belongs to, if any.
resource_id:
type: string
format: uuid
user_id:
type: string
format: uuid
description: The user behind the resource
customer_id:
type: string
format: uuid
status:
type: string
enum:
- T_ASSIGNED
- T_CONFIRMED
- T_ACKNOWLEDGED
- T_EN_ROUTE
- T_ON_SITE
- T_COMPLETED
- T_FAILED
assigned_at:
type: string
format: date-time
assigned_by:
type:
- string
- 'null'
format: uuid
description: The user who assigned it
assigned_by_system:
type: boolean
description: True when WorkWing made the assignment rather than a person.
acknowledged_at:
type:
- string
- 'null'
format: date-time
en_route_at:
type:
- string
- 'null'
format: date-time
arrived_at:
type:
- string
- 'null'
format: date-time
notes:
type:
- string
- 'null'
route_position:
type:
- integer
- 'null'
estimated_travel_duration:
type:
- integer
- 'null'
estimated_travel_distance:
type:
- integer
- 'null'
travel_eta:
type:
- string
- 'null'
format: date-time
travel_estimated_at:
type:
- string
- 'null'
format: date-time
departure_latitude:
type:
- number
- 'null'
departure_longitude:
type:
- number
- 'null'
sync_expired_at:
type:
- string
- 'null'
format: date-time
description: When the assignment stopped syncing to the mobile app after its job closed. Null while it still syncs.
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
meta:
type: object
required:
- request_id
- timestamp
properties:
request_id:
type: string
timestamp:
type: string
format: date-time
delete:
operationId: deleteAssignment
summary: Delete assignment
tags:
- Assignments
description: Remove a resource assignment from a job
parameters:
- schema:
type: string
format: uuid
in: path
name: assignmentId
required: true
- $ref: '#/components/parameters/IdempotencyKey'
security:
- bearerAuth: []
x-required-scopes:
- delete:jobs
responses:
'204':
description: Deleted. No body.
/v1/jobs/{jobId}/assignments:
get:
operationId: listJobAssignments
summary: Get job assignments
tags:
- Assignments
description: Get all resource assignments for a specific job
parameters:
- schema:
type: string
format: uuid
in: path
name: jobId
required: true
security:
- bearerAuth: []
x-required-scopes:
- read:jobs
responses:
'200':
description: Assignments, earliest first
content:
application/json:
schema:
description: Assignments, earliest first
type: object
required:
- data
- meta
properties:
data:
type: array
items:
type: object
required:
- id
- job_id
- resource_id
- status
- assigned_at
- acknowledged_at
- en_route_at
- arrived_at
- assigned_by
- created_at
- updated_at
- resource_name
- resource_email
properties:
id:
type: string
format: uuid
job_id:
type: string
format: uuid
resource_id:
type: string
format: uuid
status:
type: string
enum:
- T_ASSIGNED
- T_CONFIRMED
- T_ACKNOWLEDGED
- T_EN_ROUTE
- T_ON_SITE
- T_COMPLETED
- T_FAILED
assigned_at:
type: string
format: date-time
acknowledged_at:
type:
- string
- 'null'
format: date-time
en_route_at:
type:
- string
- 'null'
format: date-time
arrived_at:
type:
- string
- 'null'
format: date-time
assigned_by:
type:
- string
- 'null'
format: uuid
description: The user who assigned it
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
resource_name:
type:
- string
- 'null'
description: The resource's name, or their email when they have no name
resource_email:
type:
- string
- 'null'
meta:
type: object
required:
- request_id
- timestamp
properties:
request_id:
type: string
timestamp:
type: string
format: date-time
post:
operationId: createJobAssignment
summary: Assign a resource to a job
tags:
- Assignments
description: Assign a resource to a job. On a project, this adds the resource to the crew who may claim its jobs.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- resource_id
properties:
resource_id:
type: string
format: uuid
parameters:
- schema:
type: string
format: uuid
in: path
name: jobId
required: true
- $ref: '#/components/parameters/IdempotencyKey'
security:
- bearerAuth: []
x-required-scopes:
- create:jobs
responses:
'201':
description: The new assignment
content:
application/json:
schema:
description: The new assignment
type: object
required:
- data
- meta
properties:
data:
type: object
required:
- id
- job_id
- parent_job_id
- resource_id
- user_id
- customer_id
- status
- assigned_at
- assigned_by
- assigned_by_system
- acknowledged_at
- en_route_at
- arrived_at
- notes
- route_position
- estimated_travel_duration
- estimated_travel_distance
- travel_eta
- travel_estimated_at
- departure_latitude
- departure_longitude
- sync_expired_at
- created_at
- updated_at
properties:
id:
type: string
format: uuid
job_id:
type: string
format: uuid
parent_job_id:
type:
- string
- 'null'
format: uuid
description: The project the job belongs to, if any.
resource_id:
type: string
format: uuid
user_id:
type: string
format: uuid
description: The user behind the resource
customer_id:
type: string
format: uuid
status:
type: string
enum:
- T_ASSIGNED
- T_CONFIRMED
- T_ACKNOWLEDGED
- T_EN_ROUTE
- T_ON_SITE
- T_COMPLETED
- T_FAILED
assigned_at:
type: string
format: date-time
assigned_by:
type:
- string
- 'null'
format: uuid
description: The user who assigned it
assigned_by_system:
type: boolean
description: True when WorkWing made the assignment rather than a person.
acknowledged_at:
type:
- string
- 'null'
format: date-time
en_route_at:
type:
- string
- 'null'
format: date-time
arrived_at:
type:
- string
- 'null'
format: date-time
notes:
type:
- string
- 'null'
route_position:
type:
- integer
- 'null'
estimated_travel_duration:
type:
- integer
- 'null'
estimated_travel_distance:
type:
- integer
- 'null'
travel_eta:
type:
- string
- 'null'
format: date-time
travel_estimated_at:
type:
- string
- 'null'
format: date-time
departure_latitude:
type:
- number
- 'null'
departure_longitude:
type:
- number
- 'null'
sync_expired_at:
type:
- string
- 'null'
format: date-time
description: When the assignment stopped syncing to the mobile app after its job closed. Null while it still syncs.
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
meta:
type: object
required:
- request_id
- timestamp
properties:
request_id:
type: string
timestamp:
type: string
format: date-time
components:
parameters:
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
description: Unique per write, 1-256 printable ASCII characters. Retrying with the same key and the same request replays the original response for 24 hours. See Idempotency.
schema:
type: string
minLength: 1
maxLength: 256
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: API Key
description: 'Use your WorkWing API key (format: `ww_sk_live_<tokenId>.<secret>`). The scopes an operation requires are published on it as `x-required-scopes`.'