Placements

Update a placement

Changed on

Use this endpoint to partially update an existing placement. Only the fields present in the request body are changed — omitted fields are left untouched.

What you can update:

  • startDate — ISO 8601 datetime, or null to clear it
  • salary — a { value, currency } object, or null to clear both. This maps to the salary object returned by the GET endpoints
  • bonus — a decimal string denominated in the salary currency (there is no separate bonus currency), or null to clear it
  • feeIncludesBonus — boolean; null is rejected
  • commissionRate — a decimal string, or null to clear it. Unlike creation, no default is applied — the literal value is written
  • companyContactId — the hiring contact at the client company. It must belong to your agency, and to the project's company when the project has one; null clears it
  • customAttributes — full replace: every existing value not present in the payload is removed. Omit the field to leave values untouched
  • addFeeIds / removeFeeIds — link fees from the placement's project to this placement, or unlink fees currently linked to it

Permissions: Only the placement owner or an admin (a user with the Agency.update or Placement.update scope) can update a placement. The acting user is the one tied to your API key — a key whose user is neither returns 403, as does a key with no user at all.

Behaviour notes:

  • The body must be sent with Content-Type: application/json — any other content type is rejected with 415 so a payload is never silently discarded
  • A request with no body at all is rejected with 422. An explicit empty object ({}) is the documented no-op: it returns 200 and writes nothing
  • Soft-deleted placements return 404 — they cannot be updated
  • A body that changes nothing still returns 200, but no placement.updated webhook is emitted
  • A change to a scalar field (startDate, salary, bonus, feeIncludesBonus, commissionRate, companyContactId) emits the placement.updated webhook. The payload is a full snapshot of the placement, not a diff — compare it against the previous event to see what changed. Fee link/unlink and custom-attribute changes do not emit a webhook

What you get back: The full updated placement in the same shape as Get placement details, including nested salary, bonus, feeIncludesBonus, commissionRate, candidate, project, client, fees and customAttributes.

patch/api/v1/placements/{id}

Request

Path parameters

idstring uuid required

Placement ID

Example:550e8400-e29b-41d4-a716-446655440000

Request body

startDatestring date-time nullable

Placement start date (ISO 8601 datetime). null clears it

bonusstring nullable

Annual bonus (decimal string), denominated in the salary currency. null clears it

feeIncludesBonusboolean

Whether the placement fee includes the bonus. Not nullable

commissionRatestring nullable

Commission rate (decimal string). null clears it

companyContactIdstring uuid nullable

Hiring contact at the client company. Must belong to your agency (and to the project's company when the project has one). null clears it

addFeeIdsstring[]

Fee IDs to link to this placement. Fees must belong to the placement's project and not be linked to another placement

removeFeeIdsstring[]

Fee IDs to unlink from this placement. Fees must currently be linked to this placement

Example request

{
  "startDate": "2026-09-01T00:00:00Z",
  "salary": {
    "value": "25000.00",
    "currency": "USD"
  },
  "bonus": "5000.00",
  "commissionRate": "20.00"
}

Response

The updated placement, in the same shape as Get placement details

status'ok' required

Example response

{
  "data": {
    "type": "permanent",
    "salary": {
      "value": "15000",
      "currency": "GBP"
    },
    "bonus": "5000",
    "commissionRate": "20",
    "approvalStatus": "pending",
    "owner": {
      "name": "Jane Smith",
      "email": "jane@agency.com"
    },
    "candidate": {
      "name": "John Doe",
      "role": "Senior Software Engineer",
      "company": "Acme Corp",
      "owner": {
        "name": "Jane Smith"
      }
    },
    "project": {
      "owner": {
        "name": "Jane Smith"
      }
    },
    "client": {
      "company": {
        "name": "Acme Corp"
      },
      "companyContact": {
        "name": "Bob Client"
      }
    },
    "fees": [
      {
        "feeType": {
          "name": "Placement Fee"
        },
        "feeDate": "2025-06-15",
        "amount": {
          "value": "15000",
          "currency": "GBP"
        },
        "amountInAgencyCurrency": {
          "value": "15000",
          "currency": "GBP"
        },
        "projectFeeStatus": "earned",
        "createdBy": {
          "name": "Jane Smith"
        },
        "splits": [
          {
            "feeEarner": {
              "name": "Jane Smith",
              "email": "jane@agency.com"
            },
            "feeType": {
              "name": "Placement Fee"
            },
            "share": "60.00"
          }
        ]
      }
    ]
  }
}

Changes

    • warning

      added the new undefined enum value to the / response property for the response status

    • warning

      added the new undefined enum value to the /// response property for the response status

    • warning

      added the new undefined enum value to the / response property for the response status

    • info

      added the required property / to the response with the status