Skip to content

Bulk invite members ​

POST/api/v2/workspaces/{slug}/invitations/bulk/

Invite up to 100 people to a workspace in one request. Every invitee gets the same role and the same optional message, and each one is emailed an invitation link.

This endpoint doesn't use the generic bulk-write shape

Despite the bulk/ path, this endpoint does not take {items: [...]} and does not return per-row results. Its body has its own fields (emails, role, message), and it returns 201 with the invitations it created. The bulk-create, bulk-update, and bulk-delete routes on other resources follow a different contract.

Path parameters ​

slug:requiredstring

The workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.

Body parameters ​

emails:requiredarray of string (email)

The addresses to invite, at most 100 per call. Each must be a valid, non-empty email address. One malformed entry makes the whole request return 400, and no invitations are sent.

role:optionalstring

The role every invitee receives. One of admin, member, or guest. Defaults to member.

You can't give invitees different roles in one call. Send one request per role.

message:optionalstring

A note included in the invitation email, shown to every invitee in this batch.

Addresses with a pending invite are skipped without an error

Before writing, the endpoint checks which of your emails already have an outstanding invite to this workspace and leaves them out. It returns no error for them, creates no duplicate invite, and sends no second email. Those addresses don't appear in the response.

The response array lists exactly the invitations that were created. It can be shorter than the emails you sent, or empty. To report "already invited" back to a user, compare the two.

The batch is atomic

All the invitations are written inside a single transaction, so either every new invite is created or none is. Unlike the bulk-create routes on other resources, there is no partial-success envelope to inspect.

Scopes ​

workspaces.members:write

Errors ​

StatusCodeCause
400invalid_requestemails missing or empty, an invalid address, more than 100 entries, or a role outside the enum.
401unauthorizedMissing or invalid credentials.
402payment_requiredSeat limits or a plan restriction block new members.
403forbiddenYour role or token scope can't invite members to this workspace.
404not_foundNo such workspace, or it's outside your tenant.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409conflictThe write collides with existing membership state.
413payload_too_largeThe request body is over the size limit.
415unsupported_media_typeThe Content-Type isn't one this endpoint accepts.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
Bulk invite members
bash
curl -X POST \
  "https://api.plane.so/api/v2/workspaces/my-team/invitations/bulk/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "emails": ["ana@example.com", "ravi@example.com"],
  "role": "member",
  "message": "Joining the platform team this sprint."
}'
Response201
json
[
  {
    "id": "b7e42a19-3c5d-4f80-9a26-8d1c0f4e7b53",
    "email": "ana@example.com",
    "role": "member",
    "message": "Joining the platform team this sprint.",
    "accepted": false,
    "responded_at": null,
    "created_at": "2026-01-14T09:22:41.478363Z",
    "updated_at": "2026-01-14T09:22:41.478363Z",
    "created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
    "updated_by_id": null
  },
  {
    "id": "9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88",
    "email": "ravi@example.com",
    "role": "member",
    "message": "Joining the platform team this sprint.",
    "accepted": false,
    "responded_at": null,
    "created_at": "2026-01-14T09:22:41.478363Z",
    "updated_at": "2026-01-14T09:22:41.478363Z",
    "created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
    "updated_by_id": null
  }
]

Tracking who accepted ​

The response gives you an invitation id per invitee, with accepted: false and responded_at: null. Poll List invitations to see which have been accepted, or Delete an invitation to revoke one that is still outstanding.

An invitation is not a membership. Accepted invitees show up in List workspace members.