Skip to content

Create Association

This endpoint creates an association between a project and a contact.

POST /v1/associations/associations

Include your API key in the x-api-key header. See Authentication.

associations:write
FieldTypeRequiredDescription
projectIdstringYesProject ID to associate.
contactIdstringYesContact ID to associate.
contactType"MANAGER" | "BACKUP_MANAGER" | "ADDITIONAL_CONTACT"NoContact role for the project. Defaults to MANAGER.
notificationLevel"NONE" | "COPY_ONLY" | "COPY_WITH_LINK"NoNotification level for this association. Defaults to NONE.
outstandingTimecardsAction"SEND" | "NO_SEND"NoHow to handle the project’s pending timecards when the API returns 409. See Outstanding timecards.

The API does not check contactType and notificationLevel against the allowed values. Other strings are stored as sent, so send only the values listed above.

{
"projectId": "project-mno123pqr4567890",
"contactId": "contact-jkl123mno4567890",
"contactType": "MANAGER",
"notificationLevel": "COPY_ONLY"
}
Terminal window
curl -X POST "https://api.crewsum.com/v1/associations/associations" \
-H "x-api-key: $CREWSUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "project-mno123pqr4567890",
"contactId": "contact-jkl123mno4567890",
"contactType": "MANAGER",
"notificationLevel": "COPY_ONLY"
}'

On success, the API returns HTTP 200 OK. This endpoint does not return 201.

{
"message": "Successfully associated project-mno123pqr4567890 to contact-jkl123mno4567890"
}
  • The project and the contact must both exist in your account and must not be deleted.
  • A contact that belongs to a client can be associated only with that client’s projects. A contact with no client can be associated with any project.
  • A project and contact can have only one association. To change an existing association, use Update Association.
  • After the association is created, Crewsum emits the associations.created webhook event. A webhook delivery failure does not change the API response.

The API checks for pending timecards only when all of these are true:

  • notificationLevel is COPY_WITH_LINK.
  • The project has no other association with COPY_WITH_LINK.
  • The project has timecards with a pending status.

If you did not send outstandingTimecardsAction, the API returns 409 and does not create the association. The response body is {"message": "Outstanding timesheets for project found", "data": {"timecards": [...]}}. Each item in timecards describes one pending timecard, with fields such as timesheetId, projectId, taskId, status, userId, userFullName, projectName, and taskName.

Send the request again with outstandingTimecardsAction:

  • SEND: Crewsum emails the pending timecards to the contact with a link to review them, then creates the association. The emails are sent before the association is created. If the create then fails with 400 or 500, the emails have already been sent.
  • NO_SEND: Crewsum creates the association without sending emails.

When the check does not apply, the API ignores outstandingTimecardsAction.

StatusMeaning
400Project or contact not found for association: the project or the contact does not exist in your account, or is deleted.
400Cannot associate contact from another client with project: the contact belongs to a different client than the project.
409The project has pending timecards, and the request did not include outstandingTimecardsAction. See Outstanding timecards.
500Crewsum could not create the association. The message is Error associating <projectId> to <contactId>. This includes an association that already exists for the same project and contact, and a failure to send the timecard emails.
500With outstandingTimecardsAction: "SEND", Crewsum could not load the contact or the account details. The message is Could not get contact for sending timecards or Could not get tenant prefs for sending timecards.

Authentication and scope failures are described in Errors.