> ## Documentation Index
> Fetch the complete documentation index at: https://developers.projectcor.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Attach Users to Contract

> Associates one or more users with an existing contract

Associates one or more users with an existing contract. After the refactor, each user must be sent as an object with `id` and a non-empty `dates` array. The endpoint supports partial processing (`partial_success`): valid assignments are attached while rejected users or rejected date ranges are returned in `errors`.

## Path Parameters

<ParamField path="id" type="string" required>
  External contract ID
</ParamField>

## Request Body Requirements

<ParamField body="metadata" type="object" required>
  <Expandable title="properties">
    <ParamField body="source" type="string" required>
      Integration source identifier
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="users" type="array" required>
  Array of users to attach. Each item must include an external `id` and at least one date range in `dates`.

  <Expandable title="item schema">
    <ParamField body="id" type="string" required>
      External user ID
    </ParamField>

    <ParamField body="dates" type="array" required>
      Non-empty array of assignment ranges for the user.

      <Expandable title="date item schema">
        <ParamField body="start" type="string" required>
          Start date in `YYYY-MM-DD` format. Cannot be `null`.
        </ParamField>

        <ParamField body="end" type="string" required>
          End date in `YYYY-MM-DD` format. Cannot be `null`.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

## Known Errors

* `ContractNotFoundError` — No contract found with the specified external ID
* `ValidationError` — Missing required fields, invalid `users` schema, or empty `dates` array for any user
* `CE001` — User association not found in COR (`error_code: USER_ASSOCIATION_NOT_FOUND`)
* `UnprocessableEntity` (422) — Upstream attach validation errors are returned in the endpoint response body
* `Partial success date validation` — A user can be partially attached while one or more date ranges are rejected (`message: "Partial success. Some dates were rejected"`)

<RequestExample>
  ```bash cURL theme={null}
  curl --location --request PUT 'https://integrations.projectcor.com/v2/integrations/contracts/SF-CONTRACT-12345/attach' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "metadata": {
      "source": "GLOBANT"
    },
    "users": [
      {
        "id": "{{external_user_id}}",
        "dates": [
          { "start": "2027-10-01", "end": "2028-11-01" },
          { "start": "2025-10-10" }
        ]
      },
      {
        "id": "external-user-id-5",
        "dates": [
          { "start": "2025-10-02", "end": "2026-11-01" }
        ]
      }
    ]
  }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://integrations.projectcor.com/v2/integrations/contracts/SF-CONTRACT-12345/attach"

  payload = {
      "metadata": {
          "source": "GLOBANT"
      },
      "users": [
          {
              "id": "{{external_user_id}}",
              "dates": [
                  {"start": "2027-10-01", "end": "2028-11-01"},
                  {"start": "2025-10-10"}
              ]
          },
          {
              "id": "external-user-id-5",
              "dates": [
                  {"start": "2025-10-02", "end": "2026-11-01"}
              ]
          }
      ]
  }

  headers = {
      "Authorization": "Bearer YOUR_ACCESS_TOKEN",
      "Content-Type": "application/json"
  }

  response = requests.put(url, json=payload, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://integrations.projectcor.com/v2/integrations/contracts/SF-CONTRACT-12345/attach',
    {
      method: 'PUT',
      headers: {
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        metadata: {
          source: 'GLOBANT'
        },
        users: [
          {
            id: '{{external_user_id}}',
            dates: [
              { start: '2027-10-01', end: '2028-11-01' },
              { start: '2025-10-10' }
            ]
          },
          {
            id: 'external-user-id-5',
            dates: [{ start: '2025-10-02', end: '2026-11-01' }]
          }
        ]
      })
    }
  );

  const data = await response.json();
  console.log(data);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "status": "partial_success",
    "company_id": 2336,
    "contract_id": "external-contract-id-1",
    "records_received": 2,
    "records_created": 1,
    "records_rejected": 1,
    "assigned": [
      {
        "id": 18,
        "user_id": 48915,
        "start_date": "2027-10-01T00:00:00.000Z",
        "end_date": "2028-11-01T00:00:00.000Z"
      }
    ],
    "errors": [
      {
        "id": "external-user-id-5",
        "error_code": "CE001",
        "message": "User not found in associations"
      },
      {
        "id": "external_user_id_12312333333333",
        "dates": [
          {
            "start": "2025-10-10",
            "end": null,
            "message": "Date malformatted. Start and end date are required"
          }
        ],
        "message": "Partial success. Some dates were rejected"
      }
    ]
  }
  ```
</ResponseExample>
