Skip to content

Contractors

Manage contractor records in your organization. Contractors represent external individuals or firms engaged on a contract basis, with rate information and team/project assignments.

New to Flowstate?

Read the Domain Model first to understand how contractors relate to rate adjustments, teams, and projects.

Contractor Object

FieldTypeDescription
idstringUnique identifier (CUID format). System-generated. Read-only.
externalIdstring | nullYour external identifier for this contractor. Unique within your organization. Use for lookups via path parameters.
namestringContractor's display name (individual name or company representative).
emailstring | nullContact email address.
contractorTypestringType of engagement: "individual", "agency", "consultancy", or a custom value.
companyIdstring | nullID of the contracting company, if the contractor represents a firm. References another contractor record.
startDatedate (YYYY-MM-DD) | nullContract start date.
endDatedate (YYYY-MM-DD) | nullContract end date. null = open-ended engagement.
managerIdstring | nullID of the employee managing this contractor. References an Employee.
geographyIdstring | nullContractor's work location/region. References a Location.
rateTypestring | nullBilling period: "hourly", "daily", or "monthly".
ratenumber | nullCurrent billing rate amount. Decimal with 2 decimal places.
currencyCodestring | nullISO 4217 currency code for the rate (e.g. "GBP").
createdAtdatetime (ISO 8601)When the record was created. Read-only.
updatedAtdatetime (ISO 8601)When the record was last modified. Read-only.
customAttributesarrayCustom attribute values for this contractor. Returned on GET-by-ID. See Custom Attributes.

Endpoints

MethodPathDescription
GET/org/:orgId/contractorsList contractors
GET/org/:orgId/contractors/:idGet contractor
POST/org/:orgId/contractorsCreate contractor
PATCH/org/:orgId/contractors/:idUpdate contractor
DELETE/org/:orgId/contractors/:idDelete contractor

External ID Support

The :id path parameter accepts either a Flowstate CUID (e.g. clx1a2b3c4d5e6f7g8h9) or your externalId. The format is auto-detected.


List Contractors

GET /org/:orgId/contractors

Returns a paginated list of contractors in the organization.

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number (1-based).
limitinteger20Records per page. Min 1, max 100.
searchstring--Free-text search by name or email.
sortBystringnameField to sort by.
sortDirstringascSort direction: asc or desc.
scenarioIdstring--Scenario ID for what-if queries.

Example Request

bash
curl -X GET "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/contractors?limit=10&sortBy=name" \
  -H "Authorization: Bearer private_..."

Example Response

json
{
  "data": [
    {
      "id": "clx4c5d6e7f8g9h0i1j2",
      "externalId": null,
      "name": "Priya Sharma",
      "email": "priya@consultingfirm.com",
      "contractorType": "individual",
      "companyId": null,
      "startDate": "2025-01-15",
      "endDate": "2025-12-31",
      "managerId": "clx9m4n5o6p7q8r9",
      "geographyId": "clx3g2h1j0k9l8m7",
      "rateType": "hourly",
      "rate": 150.00,
      "currencyCode": "USD",
      "createdAt": "2025-01-10T08:00:00Z",
      "updatedAt": "2025-06-15T11:30:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 38,
    "hasNextPage": true
  }
}

Get Contractor

GET /org/:orgId/contractors/:id

Returns a single contractor by ID.

Use the include query parameter to embed related data:

Include KeyDescription
currentRateThe contractor's current rate adjustment (most recent by effectiveDate).
rateHistoryAll rate adjustments, ordered by effectiveDate descending.
assignmentsAll active team and project assignments.
GET /org/:orgId/contractors/:id?include=currentRate,assignments

Example Request

bash
curl -X GET "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/contractors/clx4c5d6e7f8g9h0i1j2?include=currentRate,assignments" \
  -H "Authorization: Bearer private_..."

Example Response

json
{
  "data": {
    "id": "clx4c5d6e7f8g9h0i1j2",
    "name": "Priya Sharma",
    "email": "priya@consultingfirm.com",
    "contractorType": "individual",
    "companyId": null,
    "startDate": "2025-01-15",
    "endDate": "2025-12-31",
    "managerId": "clx9m4n5o6p7q8r9",
    "geographyId": "clx3g2h1j0k9l8m7",
    "rateType": "hourly",
    "rate": 150.00,
    "currencyCode": "USD",
    "createdAt": "2025-01-10T08:00:00Z",
    "updatedAt": "2025-06-15T11:30:00Z",
    "customAttributes": [
      {
        "id": "clx9w0x1y2z3a4b5c6d7",
        "definitionId": "clx2d3e4f5g6h7i8j9k0",
        "entityType": "CONTRACTOR",
        "entityId": "clx4c5d6e7f8g9h0i1j2",
        "stringValue": "ENG-001",
        "numberValue": null,
        "dateValue": null,
        "dateRangeStart": null,
        "dateRangeEnd": null,
        "definition": {
          "id": "clx2d3e4f5g6h7i8j9k0",
          "name": "Cost Centre Code",
          "attributeKey": "cost_centre_code",
          "fieldType": "STRING"
        }
      }
    ],
    "currentRate": {
      "id": "clx7r8s9t0u1v2w3",
      "contractorId": "clx4c5d6e7f8g9h0i1j2",
      "effectiveDate": "2025-06-01",
      "rateType": "hourly",
      "rate": 150.00,
      "currencyCode": "USD",
      "reason": "Contract renewal",
      "createdAt": "2025-05-20T09:00:00Z",
      "updatedAt": "2025-05-20T09:00:00Z"
    },
    "assignments": [
      {
        "id": "clx8a9b0c1d2e3f4",
        "type": "team",
        "targetId": "clx6t7u8v9w0x1y2",
        "fte": 1.0,
        "startDate": "2025-01-15",
        "endDate": "2025-12-31",
        "createdAt": "2025-01-10T08:00:00Z",
        "updatedAt": "2025-01-10T08:00:00Z"
      }
    ]
  }
}

Create Contractor

POST /org/:orgId/contractors

Creates a new contractor record. You can optionally include nested objects to atomically create a rate adjustment, team assignment, and/or project assignment.

Create Request Body

FieldTypeRequiredDescription
namestringYesContractor's display name.
externalIdstring | nullNoYour external identifier. Must be unique within the organization. Cannot resemble a CUID format. Max 255 characters.
emailstring | nullNoContact email address. Must be a valid email if provided.
contractorTypestringYesType of engagement (e.g. "individual", "agency", "consultancy").
companyIdstring | nullNoID of the contracting company (another contractor record).
startDatedate (YYYY-MM-DD) | nullNoContract start date.
endDatedate (YYYY-MM-DD) | nullNoContract end date. null = open-ended.
managerIdstring | nullNoID of the managing employee.
geographyIdstring | nullNoLocation ID.
rateTypestring | nullNoBilling period: "hourly", "daily", or "monthly".
ratenumber | nullNoBilling rate amount. Must be >= 0.
currencyCodestring | nullNoISO 4217 currency code (3 uppercase letters).
rateAdjustmentobjectNoNested initial rate adjustment. See below.
teamAssignmentobjectNoNested team assignment. See below.
projectAssignmentobjectNoNested project assignment. See below.

Nested rateAdjustment Object

FieldTypeRequiredDescription
effectiveDatedate (YYYY-MM-DD)YesDate this rate takes effect.
rateTypestringYes"hourly", "daily", or "monthly".
ratenumberYesRate amount. Must be >= 0.
currencyCodestringYesISO 4217 currency code.
reasonstring | nullNoReason (e.g. "Initial rate").

Nested teamAssignment Object

FieldTypeRequiredDescription
teamIdstringYesID of the team.
ftenumberYesFTE allocation (0.0--10.0).
startDatedate (YYYY-MM-DD)YesAssignment start date.
endDatedate (YYYY-MM-DD) | nullNoAssignment end date. null = ongoing.
rolestring | nullNoRole within this assignment.

Nested projectAssignment Object

FieldTypeRequiredDescription
projectIdstringYesID of the project.
ftenumberYesFTE allocation (0.0--10.0).
startDatedate (YYYY-MM-DD)YesAssignment start date.
endDatedate (YYYY-MM-DD) | nullNoAssignment end date. null = ongoing.
rolestring | nullNoRole within this assignment.

Example: Simple Create

bash
curl -X POST "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/contractors" \
  -H "Authorization: Bearer private_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Marcus Johnson",
    "email": "marcus@devshop.io",
    "contractorType": "individual",
    "rateType": "daily",
    "rate": 1200,
    "currencyCode": "GBP",
    "startDate": "2026-04-01",
    "endDate": "2026-09-30"
  }'

Example: Nested Create (Contractor + Rate + Team)

bash
curl -X POST "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/contractors" \
  -H "Authorization: Bearer private_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Marcus Johnson",
    "email": "marcus@devshop.io",
    "contractorType": "individual",
    "startDate": "2026-04-01",
    "endDate": "2026-09-30",
    "geographyId": "clx3g2h1j0k9l8m7",
    "managerId": "clx9m4n5o6p7q8r9",
    "rateAdjustment": {
      "effectiveDate": "2026-04-01",
      "rateType": "daily",
      "rate": 1200,
      "currencyCode": "GBP",
      "reason": "Initial engagement rate"
    },
    "teamAssignment": {
      "teamId": "clx6t7u8v9w0x1y2",
      "fte": 1.0,
      "startDate": "2026-04-01",
      "endDate": "2026-09-30"
    }
  }'

Example Response

json
{
  "data": {
    "id": "clx8p9q0r1s2t3u4v5w6",
    "externalId": null,
    "name": "Marcus Johnson",
    "email": "marcus@devshop.io",
    "contractorType": "individual",
    "companyId": null,
    "startDate": "2026-04-01",
    "endDate": "2026-09-30",
    "managerId": "clx9m4n5o6p7q8r9",
    "geographyId": "clx3g2h1j0k9l8m7",
    "rateType": "daily",
    "rate": 1200.00,
    "currencyCode": "GBP",
    "createdAt": "2026-04-08T09:00:00Z",
    "updatedAt": "2026-04-08T09:00:00Z"
  }
}

Status: 201 Created


Update Contractor

PATCH /org/:orgId/contractors/:id

Updates one or more fields on an existing contractor. Only include the fields you want to change. You can set or update the externalId field.

Nested rateAdjustment, teamAssignment, and projectAssignment objects on update are additive -- they create new records and never overwrite existing ones.

Example Request

bash
curl -X PATCH "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/contractors/clx4c5d6e7f8g9h0i1j2" \
  -H "Authorization: Bearer private_..." \
  -H "Content-Type: application/json" \
  -d '{
    "rate": 175,
    "endDate": "2026-06-30"
  }'

Example Response

json
{
  "data": {
    "id": "clx4c5d6e7f8g9h0i1j2",
    "name": "Priya Sharma",
    "email": "priya@consultingfirm.com",
    "contractorType": "individual",
    "companyId": null,
    "startDate": "2025-01-15",
    "endDate": "2026-06-30",
    "managerId": "clx9m4n5o6p7q8r9",
    "geographyId": "clx3g2h1j0k9l8m7",
    "rateType": "hourly",
    "rate": 175.00,
    "currencyCode": "USD",
    "createdAt": "2025-01-10T08:00:00Z",
    "updatedAt": "2026-04-08T09:25:00Z"
  }
}

Delete Contractor

DELETE /org/:orgId/contractors/:id

Deletes a contractor record. This operation is permanent for live data. In scenario mode, it creates a soft-delete tombstone.

Example Request

bash
curl -X DELETE "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/contractors/clx4c5d6e7f8g9h0i1j2" \
  -H "Authorization: Bearer private_..."

Status: 204 No Content


External IDs

You can assign your own externalId during creation or update. This allows you to reference contractors by your system's identifier instead of the Flowstate CUID.

  • Setting: Pass externalId in the POST or PATCH request body.
  • Lookups: Use the external ID directly in path parameters (e.g. GET /contractors/MY-EXT-ID).
  • Uniqueness: External IDs must be unique per entity type within your organization.
  • Format restriction: External IDs cannot match the CUID format (25 lowercase alphanumeric characters starting with a letter).

Error Responses

Validation Error (400)

json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed.",
    "details": [
      { "field": "contractorType", "message": "contractorType is required" }
    ],
    "errorId": "err_clx9a8b7c6d5e4f3"
  }
}

Not Found (404)

json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Contractor not found.",
    "errorId": "err_clx9a8b7c6d5e4f3"
  }
}

Flowstate Documentation