workwing-io Custom Fields API

Custom field definitions: the schema (keys, labels, types) for job, customer and resource custom fields. Read them for discovery, create and update them to define the fields an integration fills in. Set values via each entity's custom-fields endpoint.

Operations 3

GET /v1/custom-field-definitions List custom field definitions #
POST /v1/custom-field-definitions Create a custom field definition #
PATCH /v1/custom-field-definitions/{id} Update a custom field definition #

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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/workwing-io:workwing-io-custom-fields-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

workwing-io-custom-fields-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: WorkWing Custom Fields 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: Custom Fields
  description: 'Custom field definitions: the schema (keys, labels, types) for job, customer and resource custom fields. Read them for discovery, create and update them to define the fields an integration fills in. Set values via each entity''s custom-fields endpoint.'
paths:
  /v1/custom-field-definitions:
    get:
      operationId: listCustomFieldDefinitions
      summary: List custom field definitions
      tags:
      - Custom Fields
      description: 'List active custom field definitions (the schema: key, label, type, and whether required) for your organisation. Filter with `?entity_type=T_JOB` (or `T_CUSTOMER` / `T_RESOURCE`).


        Set values with `PATCH /v1/jobs/{jobId}/custom-fields` (and the equivalent customer and resource endpoints), which reference these definitions by `field_key`.'
      parameters:
      - schema:
          type: string
          enum:
          - T_JOB
          - T_CUSTOMER
          - T_RESOURCE
        in: query
        name: entity_type
        required: false
        description: Filter to one entity type
      security:
      - bearerAuth: []
      x-required-scopes:
      - read:custom_field_definitions
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                - meta
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      required:
                      - id
                      - entity_type
                      - template_id
                      - field_key
                      - field_label
                      - field_description
                      - field_type
                      - field_config
                      - display_order
                      - display_section
                      - display_width
                      - is_required
                      - is_active
                      - is_searchable
                      - is_filterable
                      - created_at
                      - updated_at
                      - created_by_user_id
                      properties:
                        id:
                          type: string
                          format: uuid
                        entity_type:
                          type: string
                          enum:
                          - T_JOB
                          - T_CUSTOMER
                          - T_RESOURCE
                        template_id:
                          type:
                          - string
                          - 'null'
                          format: uuid
                          description: Set when the field belongs to one job type (defined in the form builder). Null for tenant-wide fields, which is every field created over the API.
                        field_key:
                          type: string
                        field_label:
                          type: string
                        field_description:
                          type:
                          - string
                          - 'null'
                        field_type:
                          type: string
                          enum:
                          - T_TEXT
                          - T_TEXTAREA
                          - T_NUMBER
                          - T_DATE
                          - T_DATETIME
                          - T_BOOLEAN
                          - T_SELECT
                          - T_MULTISELECT
                          - T_URL
                          - T_EMAIL
                          - T_PHONE
                          - T_SCANNER
                        field_config:
                          type:
                          - object
                          - 'null'
                          additionalProperties: true
                          description: 'Type-specific settings: minLength/maxLength/pattern for text, min/max/step/unit for numbers, minDate/maxDate for dates, options for select and multiselect, allowedBarcodeTypes/scannerHint for scanner.'
                        display_order:
                          type:
                          - integer
                          - 'null'
                        display_section:
                          type:
                          - string
                          - 'null'
                        display_width:
                          type:
                          - string
                          - 'null'
                          enum:
                          - T_FULL
                          - T_HALF
                          - T_THIRD
                          - null
                        is_required:
                          type:
                          - boolean
                          - 'null'
                        is_active:
                          type:
                          - boolean
                          - 'null'
                        is_searchable:
                          type:
                          - boolean
                          - 'null'
                        is_filterable:
                          type:
                          - boolean
                          - 'null'
                        created_at:
                          type:
                          - string
                          - 'null'
                          format: date-time
                        updated_at:
                          type:
                          - string
                          - 'null'
                          format: date-time
                        created_by_user_id:
                          type:
                          - string
                          - 'null'
                          format: uuid
                  meta:
                    type: object
                    required:
                    - request_id
                    - timestamp
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                        format: date-time
    post:
      operationId: createCustomFieldDefinition
      summary: Create a custom field definition
      tags:
      - Custom Fields
      description: 'Define a new custom field on jobs, customers or resources for your whole organisation. Requires `create:custom_field_definitions`.


        `entity_type`, `field_key` and `field_type` are fixed once created. `is_required` defaults to false; `is_searchable` and `is_filterable` default to true. The new field appears in the layout and form builder palettes; placing it on a form is done in the web app.


        Returns 409 when a field with the same key already exists on that entity.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - entity_type
              - field_key
              - field_label
              - field_type
              additionalProperties: true
              properties:
                entity_type:
                  type: string
                  enum:
                  - T_JOB
                  - T_CUSTOMER
                  - T_RESOURCE
                field_key:
                  type: string
                  pattern: ^[a-z0-9_]+$
                  description: Stable key the value is stored against (lowercase letters, digits, underscores)
                field_type:
                  type: string
                  enum:
                  - T_TEXT
                  - T_TEXTAREA
                  - T_NUMBER
                  - T_DATE
                  - T_DATETIME
                  - T_BOOLEAN
                  - T_SELECT
                  - T_MULTISELECT
                  - T_URL
                  - T_EMAIL
                  - T_PHONE
                  - T_SCANNER
                field_label:
                  type: string
                field_description:
                  type:
                  - string
                  - 'null'
                display_section:
                  type:
                  - string
                  - 'null'
                is_required:
                  type: boolean
                is_searchable:
                  type: boolean
                is_filterable:
                  type: boolean
                field_config:
                  type: object
                  additionalProperties: true
                  description: 'Type-specific settings: minLength/maxLength/pattern for text, min/max/step/unit for numbers, minDate/maxDate for dates, options for select and multiselect, allowedBarcodeTypes/scannerHint for scanner.'
      security:
      - bearerAuth: []
      x-required-scopes:
      - create:custom_field_definitions
      responses:
        '201':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                - meta
                properties:
                  data:
                    type: object
                    required:
                    - id
                    - entity_type
                    - template_id
                    - field_key
                    - field_label
                    - field_description
                    - field_type
                    - field_config
                    - display_order
                    - display_section
                    - display_width
                    - is_required
                    - is_active
                    - is_searchable
                    - is_filterable
                    - created_at
                    - updated_at
                    - created_by_user_id
                    properties:
                      id:
                        type: string
                        format: uuid
                      entity_type:
                        type: string
                        enum:
                        - T_JOB
                        - T_CUSTOMER
                        - T_RESOURCE
                      template_id:
                        type:
                        - string
                        - 'null'
                        format: uuid
                        description: Set when the field belongs to one job type (defined in the form builder). Null for tenant-wide fields, which is every field created over the API.
                      field_key:
                        type: string
                      field_label:
                        type: string
                      field_description:
                        type:
                        - string
                        - 'null'
                      field_type:
                        type: string
                        enum:
                        - T_TEXT
                        - T_TEXTAREA
                        - T_NUMBER
                        - T_DATE
                        - T_DATETIME
                        - T_BOOLEAN
                        - T_SELECT
                        - T_MULTISELECT
                        - T_URL
                        - T_EMAIL
                        - T_PHONE
                        - T_SCANNER
                      field_config:
                        type:
                        - object
                        - 'null'
                        additionalProperties: true
                        description: 'Type-specific settings: minLength/maxLength/pattern for text, min/max/step/unit for numbers, minDate/maxDate for dates, options for select and multiselect, allowedBarcodeTypes/scannerHint for scanner.'
                      display_order:
                        type:
                        - integer
                        - 'null'
                      display_section:
                        type:
                        - string
                        - 'null'
                      display_width:
                        type:
                        - string
                        - 'null'
                        enum:
                        - T_FULL
                        - T_HALF
                        - T_THIRD
                        - null
                      is_required:
                        type:
                        - boolean
                        - 'null'
                      is_active:
                        type:
                        - boolean
                        - 'null'
                      is_searchable:
                        type:
                        - boolean
                        - 'null'
                      is_filterable:
                        type:
                        - boolean
                        - 'null'
                      created_at:
                        type:
                        - string
                        - 'null'
                        format: date-time
                      updated_at:
                        type:
                        - string
                        - 'null'
                        format: date-time
                      created_by_user_id:
                        type:
                        - string
                        - 'null'
                        format: uuid
                  meta:
                    type: object
                    required:
                    - request_id
                    - timestamp
                    properties:
                      request_id:
                        type: string
                      timestamp:
                        type: string
                        format: date-time
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
  /v1/custom-field-definitions/{id}:
    patch:
      operationId: updateCustomFieldDefinition
      summary: Update a custom field definition
      tags:
      - Custom Fields
      description: 'Update the label, description, section, flags or type-specific settings of a definition, or deactivate it with `{"is_active": false}` (stored values are kept). Requires `update:custom_field_definitions`.


        `entity_type`, `field_key` and `field_type` cannot be changed; a body naming them is rejected with 400.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
              properties:
                field_label:
                  type: string
                field_description:
                  type:
                  - string
                  - 'null'
                display_section:
                  type:
                  - string
                  - 'null'
                is_required:
                  type: boolean
                is_searchable:
                  type: boolean
                is_filterable:
                  type: boolean
                field_config:
                  type: object
                  additionalProperties: true
                  description: 'Type-specific settings: minLength/maxLength/pattern for text, min/max/step/unit for numbers, minDate/maxDate for dates, options for select and multiselect, allowedBarcodeTypes/scannerHint for scanner.'
                is_active:
                  type: boolean
                  description: false deactivates the field and hides it from forms and the list; values are kept
      parameters:
      - schema:
          type: string
          format: uuid
        in: path
        name: id
        required: true
      - $ref: '#/components/parameters/IdempotencyKey'
      security:
      - bearerAuth: []
      x-required-scopes:
      - update:custom_field_definitions
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                - meta
                properties:
                  data:
                    type: object
                    required:
                    - id
                    - entity_type
                    - template_id
                    - field_key
                    - field_label
                    - field_description
                    - field_type
                    - field_config
                    - display_order
                    - display_section
                    - display_width
                    - is_required
                    - is_active
                    - is_searchable
                    - is_filterable
                    - created_at
                    - updated_at
                    - created_by_user_id
                    properties:
                      id:
                        type: string
                        format: uuid
                      entity_type:
                        type: string
                        enum:
                        - T_JOB
                        - T_CUSTOMER
                        - T_RESOURCE
                      template_id:
                        type:
                        - string
                        - 'null'
                        format: uuid
                        description: Set when the field belongs to one job type (defined in the form builder). Null for tenant-wide fields, which is every field created over the API.
                      field_key:
                        type: string
                      field_label:
                        type: string
                      field_description:
                        type:
                        - string
                        - 'null'
                      field_type:
                        type: string
                        enum:
                        - T_TEXT
                        - T_TEXTAREA
                        - T_NUMBER
                        - T_DATE
                        - T_DATETIME
                        - T_BOOLEAN
                        - T_SELECT
                        - T_MULTISELECT
                        - T_URL
                        - T_EMAIL
                        - T_PHONE
                        - T_SCANNER
                      field_config:
                        type:
                        - object
                        - 'null'
                        additionalProperties: true
                        description: 'Type-specific settings: minLength/maxLength/pattern for text, min/max/step/unit for numbers, minDate/maxDate for dates, options for select and multiselect, allowedBarcodeTypes/scannerHint for scanner.'
                      display_order:
                        type:
                        - integer
                        - 'null'
                      display_section:
                        type:
                        - string
                        - 'null'
                      display_width:
                        type:
                        - string
                        - 'null'
                        enum:
                        - T_FULL
                        - T_HALF
                        - T_THIRD
                        - null
                      is_required:
                        type:
                        - boolean
                        - 'null'
                      is_active:
                        type:
                        - boolean
                        - 'null'
                      is_searchable:
                        type:
                        - boolean
                        - 'null'
                      is_filterable:
                        type:
                        - boolean
                        - 'null'
                      created_at:
                        type:
                        - string
                        - 'null'
                        format: date-time
                      updated_at:
                        type:
                        - string
                        - 'null'
                        format: date-time
                      created_by_user_id:
                        type:
                        - string
                        - 'null'
                        format: uuid
                  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`.'