---
title: "User Invitations Create Create"
method: POST
path: "/user/invitations/create/"
tags: ["users"]
---

# User Invitations Create Create

`POST /user/invitations/create/`

Plug-and-play plan-level count-limit enforcement on resource creation.

A view declares ONE resource tag — its ``permission_resource`` (the same
``Resources`` value that drives the RBAC permission) — and this mixin hooks
``create()`` to enforce that resource's plan count limit automatically. No
separate ``plan_limited_resource``: the resource tag is the single source.

    class DatasetsView(PlanLimitMixin, PermissionMapMixin, ListCreateAPIView):
        permission_resource = Resources.DATASETS
        # RBAC perm AND the dataset count cap both derive from this tag.

The "what" (model/field/filters/error per resource) lives in the
``utils.plan_limits`` registry; ``PLAN_LIMIT_BY_RESOURCE`` maps the resource
tag → its ``GatedResource``. A tag with no registry entry simply has no cap.

How the hook fires: DRF's ``ListCreateAPIView.post()`` delegates to
``self.create()``, and views that override ``post()`` end with
``super().post()`` — both reach this mixin's ``create()`` (it sits before
the generic view in the MRO). Views that define their own ``create()`` just
need to call ``super().create()`` and honour its return value.

Org resolution: ``get_limit_organization()`` defaults to the view's
``get_organization()`` (the org the resource is created under, after any
superadmin injection), falling back to the request user's org. Override it
for bespoke resolution (e.g. a superadmin *target* org).

Custom non-``create()`` handlers (e.g. an ``update_or_create`` upsert) can't
be hooked; those call ``enforce_declared_limit()`` explicitly — still driven
off the same resource tag.

Staff exemption: Respan staff acting on an org's behalf bypass ALL plan
limits — a cross-cutting policy enforced centrally in
``enforce_declared_limit`` (see ``is_plan_limit_exempt``), not re-stated per
view. Every gated resource inherits it.

## Headers

- `Authorization` string, required

## Request body

- InvitationCreateRequest
  - `email` string, email, required
  - `organization` integer, required
  - `role` 'member' | 'admin' | 'owner' | 'keywordsai_admin' | 'annotator' — * `member` - member * `admin` - admin * `owner` - owner * `keywordsai_admin` - keywordsai_admin * `annotator` - annotator
  - `message` string
  - `from_host` string

## Response `201`

- InvitationCreate
  - `email` string, email, required
  - `organization` integer, required
  - `role` 'member' | 'admin' | 'owner' | 'keywordsai_admin' | 'annotator' — * `member` - member * `admin` - admin * `owner` - owner * `keywordsai_admin` - keywordsai_admin * `annotator` - annotator
  - `temp_role` string, required
  - `message` string

---

[API](https://skmtc.net/keywordsai/apis/api-reference.md) · [All operations](https://skmtc.net/keywordsai/apis/api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/keywordsai/api-reference/versions/c26d550029f8/schema)
