Examplary
Start for free
Developer docs

Managing permissions

Examplary uses a role-based and permission-based access control system to manage what users can do within an organization.

Roles and permissions can be managed through the Examplary web application or via the API.

Available roles

The following roles can be assigned to actors (users, groups, or organizations) on a resource:

RoleDescription
ownerFull control over the resource, including the ability to delete it. Can only be removed or downgraded by another owner.
managerCan edit the resource and manage its permissions (add/remove collaborators), but cannot grant the owner role, or remove or downgrade an existing owner's permission.
editorCan edit the resource, but cannot manage permissions.
viewerRead-only access to the resource.
participantFor students: can take an exam or access a practice space, but cannot edit or view settings.

A resource can have multiple owners. To prevent it from ending up ownerless, an owner can never remove or downgrade their own owner permission — only another owner can do that for them. The same restriction applies when the owner role is granted to a group actor: only another owner can remove or downgrade that group's owner permission.

Giving a user access to a content item

You can assign a permission by actor ID:

POST /permissions/exam_1234
{
  "actor": "user_5678",
  "role": "manager"
}

The actor field accepts a user_, group_, or org_ prefixed ID — or the literal org_this as a shortcut for your own org's ID — plus a public option covered below. Two constraints are enforced by the API for these non-public actors:

  • An org_ actor must be the requester's own org, except for library collections (lib_coll_), which can be explicitly shared with a different organization this way.
  • For a user_ actor, role must be participant if and only if the target user is a student; assigning participant to a teacher/admin, or a higher role to a student, returns a 400. This doesn't apply to group_/org_ actors.

actor also accepts the literal public, restricted to resources whose ID starts with lib_coll_ (library collections) — assigning it on any other resource type returns a 400. The /library endpoints themselves still require authentication regardless of this permission; granting public a role only controls whether the collection's items are indexed for GET /search/tokens/public, an unauthenticated endpoint that mints a search token scoped to publicly shared items.

Alternatively, you can invite a user by email address instead of an actor ID. If the user does not yet exist in your workspace, they will be created automatically — as a student if role is participant, otherwise as a teacher. Set sendInvite to true to send them an invitation email. Students can't invite new users this way (403), and teachers can be blocked from inviting via the sharingBlockTeachersInvitingUsers org setting:

POST /permissions/exam_1234
{
  "email": "user@example.com",
  "role": "manager",
  "sendInvite": true
}

Listing permissions for a content item

GET /permissions/exam_1234
[
  {
    "actor": {
      "id": "user_5678",
      "name": "Jane Smith",
      "avatar": "https://cdn.examplary.ai/avatars/user_5678.jpg",
      "type": "user",
      "orgRole": "admin"
    },
    "role": "manager",
    "createdAt": "2024-01-15T12:34:56Z",
    "updatedAt": "2024-01-20T09:21:43Z",
    "createdBy": "user_9012"
  },
  {
    "actor": {
      "id": "group_9012",
      "name": "Teaching Staff",
      "type": "group"
    },
    "role": "viewer",
    "createdAt": "2024-01-15T12:34:56Z",
    "updatedAt": "2024-01-20T09:21:43Z",
    "createdBy": "user_9012",
    "inheritedFrom": {
      "object": "folder_3456",
      "type": "folder",
      "name": "Shared Resources",
      "role": "viewer"
    }
  }
]

The actor object contains the following fields:

FieldTypeDescription
idstringThe actor's ID (user, group, or org prefixed, or the literal public).
namestringThe actor's display name. Falls back to "Unknown user", "Unknown organization", or "Unknown group" if the actor could not be resolved.
avatarstringURL to the actor's avatar image. Only present for users and orgs with a logo.
typestringThe type of actor: "user", "group", "org", or "public" (name "Public", for library collections shared publicly — see above).
orgRolestringThe actor's role in the organization. Only present for user type actors.

When an item is inside a shared folder, the permissions list also includes actors who have access through that folder. These entries include an inheritedFrom field indicating the folder they inherited access from. Inherited permissions cannot be removed via DELETE /permissions/:resource/:actor — the call still returns { "success": true }, but the actor keeps their access since there is no direct grant on the item to revoke. To revoke inherited access, update the permissions on the folder itself.

Getting the role of a specific actor

GET /permissions/exam_1234/user_5678
{
  "actor": {
    "id": "user_5678",
    "name": "Jane Smith",
    "avatar": "https://cdn.examplary.ai/avatars/user_5678.jpg",
    "type": "user",
    "orgRole": "admin"
  },
  "role": "manager",
  "createdAt": "2024-01-15T12:34:56Z",
  "updatedAt": "2024-01-20T09:21:43Z",
  "createdBy": "user_9012"
}

Use me instead of an actor ID (GET /permissions/exam_1234/me) to get the authenticated user's own role on a resource.

Autocompleting users and groups

To populate a "share with" UI, search for users and groups by name or email:

GET /permissions/autocomplete?q=jane
[
  {
    "id": "user_5678",
    "name": "Jane Smith",
    "email": "jane@example.com",
    "avatar": "https://cdn.examplary.ai/avatars/user_5678.jpg",
    "type": "user"
  },
  {
    "id": "group_9012",
    "name": "Jane's Class",
    "type": "group"
  }
]

email and avatar are only present on user results.

ParameterRequiredDescription
qYesSearch term, matched against name or email. Must be at least 3 characters.
typeNoRestrict results to one kind of actor: user or group.
roleNoFilter users by their organization role (the same role reported as orgRole on user actors above, not a resource permission role).

The authenticated user is never included in the results. If the organization has restrictGroupVisibility enabled, non-admin users only see users and groups they share a group with.

Removing a permission

DELETE /permissions/exam_1234/user_5678

Returns { "success": true } on success.