---
title: "Invite people to a project (the route Onplana Schedule and the Onplana Tasks apps call)"
method: POST
path: "/projects/{id}/share-invite"
tags: ["projects"]
---

# Invite people to a project (the route Onplana Schedule and the Onplana Tasks apps call)

`POST /projects/{id}/share-invite`

## Request

- Base URL: `https://api.onplana.com/api`
- URL: `https://api.onplana.com/api/projects/{id}/share-invite`
- Auth: one of:
  - HTTP bearer
  - API key in header `Authorization`

Accepts a session, a token holding PROJECTS_WRITE (the Onplana Schedule grant), or TASKS_WRITE from an OAuth app token (the Onplana Tasks grant). A personal access token holding TASKS_WRITE without PROJECTS_WRITE gets 403 PERSONAL_TOKEN_REFUSED. Also refused: an unverified sender (403 EMAIL_UNVERIFIED), a demo workspace (403 SANDBOX_REFUSED), and anyone who is not the project's Owner or Manager (403 PROJECT_INVITE_DENIED; organization admins pass). The seat cap, the approval rule for a paid seat and the hourly send limit are the same as the web's. The Tasks apps send no role or orgRole, so their invitations are guests. With handOverTaskId, a task assigned to the caller is marked to move to the invitee when they accept; it is checked before anything is sent: 400 HANDOVER_ONE_PERSON, 404 TASK_NOT_FOUND, 403 TASK_EDIT_DENIED, 409 HANDOVER_NOT_YOURS.

## Path parameters

- `id` string, required

## Headers

- `X-Organization-Id` string, required

## Request body

- object
  - `emails` string[], required
  - `role` 'MANAGER' | 'MEMBER' | 'CONTRIBUTOR' | 'VIEWER': Project role. OWNER is never handed out here.
  - `orgRole` 'GUEST' | 'MEMBER': The seat for someone new to the workspace
  - `handOverTaskId` string: A task assigned to the caller in this project, to move to the invitee on accept. Exactly one address.

## Response `200`

{ invited, added, requested, rateLimited, seatLimited, results[{ email, status, emailStatus?, userId? }], retryAfterSec?, seatLimit?, currentPlan?, handOver?: { taskId, marked } }. userId is on added and already-a-member rows.

## Other responses

- `400`: Validation error
- `401`: Unauthorized - missing or invalid JWT
- `403`: Forbidden - insufficient role
- `404`: Project, or the hand-over task, not found
- `409`: HANDOVER_NOT_YOURS: the task is not assigned to the caller

---

[API](https://skmtc.dev/onplana/apis/onplana-api.md) · [All operations](https://skmtc.dev/onplana/apis/onplana-api/llms.txt) · [OpenAPI document](https://skmtc.dev/onplana/apis/onplana-api/revisions/c3d6c89e9dc8?raw)
