Role based planning using unassigned roles

Unassigned roles let you plan with roles like “Developer”, “Editor”, or “Unit Manager” before you know the exact people. In the API, these are handled via special role placeholders that behave like people for scheduling and reporting.

This tutorial covers:

How unassigned roles work in the API

In the UI you can add roles to a project without picking a person. In the API, Float does this by creating a role placeholder automatically when you add a role_id to the project team. That placeholder is given a people_id behind the scenes so it can be scheduled like any other person and included in reports.

  • A role must be assigned to at least one person before it can be used in a project.
  • When you expand the project team you’ll see the role_id for roles used on the project.
  • Allocations are created and read through the /tasks endpoint (historical name) and it requires a people_id. That’s why a placeholder person is created for each role you add.
  • The placeholder is a people_id with a people_type_id of 4 (role placeholder).
  • Listing people via the /people endpoint won’t automatically include these role placeholders, but if you include the people_type_id=4 parameter, they will be included in the results.
  • For product context on what roles are, see the Help Center article on role based planning with unassigned roles.

Add a role to a project (and return a role placeholder)

When you add a role to a project team, Float will create a role placeholder and return it as a person in the project_team model. Use ?expand=project_team to see the result.
See the PATCH /projects/{project_id} endpoint in the API reference for full details.

Request

PATCH https://api.float.com/v3/projects/{project_id}?expand=project_team
Authorization: Bearer {TOKEN}
Content-Type: application/json

{
  "project_team": {
    "add": [
      {
        "people_id": null,
        "role_id": 2137,
        "hourly_rate": null
      }
    ]
  }
}

Response (trimmed)

{
  "project_id": 7845018,
  "name": "Example Project",
  "project_team": [
    {
      "people_id": 18484001,
      "role_id": 2137,
      "hourly_rate": null,
      "phase_id": 0
    }
  ]
}
  • The important part is that you now have a people_id for the role placeholder (e.g., 18484001).
  • The “Managing your projects” tutorial shows this pattern in context. (developer.float.com)

Tip: You can add the same role_id multiple times; each addition returns a distinct placeholder people_id. In your data you’ll want to keep a per‑project mapping of role_id → [people_id, …] e.g. in a table or external data source.


Create allocations for the placeholder

Once you have the placeholder people_id, you create allocations the same way you do for any person using /tasks.

Request

POST https://api.float.com/v3/tasks
Authorization: Bearer {TOKEN}
Content-Type: application/json

{
  "people_id": 18484001,          
  "project_id": 7845018,
  "phase_id": 367353,             
  "start_date": "2025‑10‑15",
  "end_date": "2025‑10‑17",
  "hours": 8,
  "name": "On‑site support"
}

The Scheduling your team tutorial explains how the create allocations endpoint is used to allocate people to work.


Fetch role‑based allocations

You can filter allocations by people_id (placeholder) as well as the date range:

GET https://api.float.com/v3/tasks?start_date=2025‑10‑13&end_date=2025‑10‑18&people_id=18484001
Authorization: Bearer {TOKEN}

Add expand for convenience (e.g., expand=client_id,people) to include related labels/ids in the payload. See the retrieve an allocation reference in the API docs.


Reporting: where do role allocations appear?

Because role placeholders are real “people” objects for scheduling purposes, their allocations roll up into project reporting alongside everyone else. Use the Reports endpoints or UI reports to aggregate hours, costs or bill rates.

  • The projects report aggregates scheduled vs actuals at project and phase levels — role‑based work is included once scheduled.
  • The API Reports reference in the docs shows how to query reports with filters including project_id, start_date, end_date etc.

Practical takeaway: If your pipeline already consumes project/people/task data, you don’t need special handling for “roles” in the reporting — treat placeholder allocations like any other person allocation and join back to the role via your mapping.


Because a single role (e.g., “Developer”) can be added multiple times to a project and produce multiple placeholder people_ids, keep a simple mapping table per project:

project_id role_id role_name placeholder_people_ids
7845018 2137 Unit Manager [18484001, 18484222, …]

How to maintain it:

  1. Query your roles master for role_id and name.
  2. Every time you PATCH the project team with a role_id, record the returned people_id.
  3. When you upsert allocations (via update an allocation), use those placeholder people_ids.
  4. If later you or someone in the UI replaces the placeholder with a real person, refresh the mapping from /projects.

Spreadsheet users: you could store the mapping in a dedicated sheet and use it to drive your allocation script or reconciliation.


End‑to‑end example

A. Add roles to the project team and capture placeholders

PATCH https://api.float.com/v3/projects/7845018?expand=project_team
Authorization: Bearer {TOKEN}
Content-Type: application/json

{
  "project_team": {
    "add": [
      { "people_id": null, "role_id": 2137 },
      { "people_id": null, "role_id": 2137 }
    ]
  }
}

Response (excerpt)

"project_team": [
  { "people_id": 18484001, "role_id": 2137 },
  { "people_id": 18484222, "role_id": 2137 }
]

Update your mapping:

  • Role 2137 → placeholder people_ids [18484001, 18484222]

B. Create allocations for each placeholder

POST https://api.float.com/v3/tasks
Authorization: Bearer {TOKEN}
Content-Type: application/json

{ "people_id": 18484001, "project_id": 7845018, "start_date": "2025‑10‑15", "end_date": "2025‑10‑17", "hours": 8 }
POST https://api.float.com/v3/tasks
Authorization: Bearer {TOKEN}
Content-Type: application/json

{ "people_id": 18484222, "project_id": 7845018, "start_date": "2025‑10‑16", "end_date": "2025‑10‑18", "hours": 6 }

C. Fetch allocations for reporting or reconciliation

GET https://api.float.com/v3/tasks?start_date=2025‑10‑13&end_date=2025‑10‑20&project_id=7845018
Authorization: Bearer {TOKEN}

Then group by people_id, use your mapping to convert to role names, and produce totals per‑role. You can also hit the Reports endpoints if desired.


FAQs & pitfalls

Q: Can I allocate directly to a role_id without creating placeholders?
A: No – the allocations endpoint requires a people_id. The required approach is to add the role to the project team, which returns a placeholder, and then create allocatations using the people_id of that placeholder.

Q: How do I see which roles are on a project over the API?
A: Use GET /v3/projects/:id?expand=project_team. The returned project_team items include role_id.

Q: Will role‑based allocations appear in project reports?
A: Yes — once scheduled, they are just allocations tied to a person (the placeholder), and roll up like any other work in project reports.

Q: Why can’t I add a newly created role to a project?
A: If you see this message: "At least one person in your company must have this role before it can be assigned to a project." It means a role must be assigned to a person before it can be used in a project team, this is to ensure all unassigned roles will eventually be assigned to a seat on the schedule.

Q: Where can I find the canonical endpoints and patterns?
A: See the Float API docs home, the Managing your projects tutorial, and the Scheduling your team tutorial.


Troubleshooting

  • I added a role, but I don’t see anything to schedule.
    Make sure you added it via the project team "add" array and that you included ?expand=project_team in the request so you receive the people_id.
  • My script can’t reconcile roles to allocations.
    Ensure you’re capturing the mapping of role_id → placeholder people_id(s) and using those people_ids when creating allocations. If a placeholder gets replaced by a real person in the UI, refresh your mapping via projects.