Skip to content

License Management API

Overview

License Management API allows you to reallocate Grammarly licenses within your software asset management tool for better utilization and IT governance. You can programmatically access your subscription summary, list of users and their last activity dates, as well as automatically de-provision users according to custom criteria. For example, you may want to de-provision users who have been inactive for 90 days or more.

This developer guide explains how to get the subscription summary, get the list of users, remove users from the subscription, and more, to streamline and automate managing your Grammarly enterprise licenses. The API is intended for programmatic consumption. Organizations can access the API through an HTTP REST interface.

Get a list of users

GET https://api.grammarly.com/ecosystem/api/v1/users

This API endpoint retrieves a paginated list of users associated with a Grammarly institution. Each user object in the response includes the user ID, institution ID, email, name, admin identifier, and last activity timestamp.

Request Parameters

ParameterTypeRequiredDescription
limitIntegerNoSpecifies the maximum number of user records to return per request. The minimum possible value is 1, while the maximum is 250. If the parameter is missing, it will default to 100.
cursorStringNoSpecifies the starting point of the records to return, enabling pagination. When it’s not passed, the API will return the first set of users. The value in the returned next_cursor should be set to this cursor value to get the next page set.

Example Request

An example cURL request to get the first ten users:

bash
curl -X GET \ 
  'https://api.grammarly.com/ecosystem/api/v1/users?limit=10&cursor=XaB4' \ 
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response Format

The response is a JSON object that includes an array of user objects and a paging containing information about the data returned.

Response Parameters

ParameterTypeDescription
dataArrayAn array of user objects containing user details (described below).
pagingObjectAn object containing info about the returned response (described below).

Each user object in the data array has the following structure:

FieldTypeDescription
user_idIntegerA unique identifier for the user.
institution_idIntegerThe ID of the institution the user is associated with.
emailStringThe user’s email address.
nameStringThe full name of the user.
last_activity_atStringTimestamp of the user’s last recorded activity in ISO 8601
is_adminBooleanA boolean to identify if that user is an admin or not. Please note that we don’t support removing admin licenses at this time.

The paging object has the following structure:

FieldTypeDescription
next_cursorStringSet to the cursor that can be used to get the next set of users. It will not be available if no more data exists (reflected also in has_more below).
cur_cursorStringSet to the cursor passed in the request or not available if nothing existed.
has_moreBooleanSet to true if more data exists and can be requested.
page_sizeIntegerThe total number of elements in the data array above.

Example Response

An example response body:

json
{
  "data": [
    {
      "user_id": 1234567890,
      "institution_id": 6123456789,
      "email": "john.doe@grammarly.com",
      "name": "John Doe",
      "last_activity_at": "2024-10-09T23:00:35.834Z",
      "is_admin": true
    },
    {
      "user_id": 1234567891,
      "institution_id": 6123456789,
      "email": "Jane.Doe@grammarly.com",
      "name": "Jane Doe",
      "last_activity_at": "2024-09-07T00:33:01.006Z",
      "is_admin": false
    }
  ],
  "paging": {
    "next_cursor": "MTYzNTc5NDQ1",
    "cur_cursor": "OTIyNzQ3OTM=",
    "has_more": true,
    "page_size": 2
  }
}

Usage Notes

Use limit and cursor parameters to manage pagination through the user list.

The last_activity_at field helps track recent user engagement and is formatted in UTC. If the user had no activity at all, this field will be set to the time the user was created.

Remove the user from the institution

DELETE https://api.grammarly.com/ecosystem/api/v1/users/{userId}

This endpoint deletes a specified user from the Institution by their unique user ID.

Request Parameters

ParameterTypeRequiredDescription
userIdIntegerYesThe unique identifier of the user to delete.

Example Request

An example cURL request to delete a user:

bash
curl -X DELETE \ 
  'https://api.grammarly.com/ecosystem/api/v1/users/1234567890' \ 
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response Format

A successful response typically contains a status code indicating the user was deleted. If the user was not found or the deletion failed, an error response is returned.

Successful Response (204 No Content)

If the deletion is successful, the server will return a 204 No Content response, indicating that the user was deleted successfully and no content is returned in the body.

Error Responses

Status CodeDescription
403Insufficient permissions to delete the user.
404The user with the specified ID was not found.
409The user is part of another institution and can’t be removed.
500Server error during deletion.

Get a list of invitees

GET https://api.grammarly.com/ecosystem/api/v1/invitees

This API endpoint retrieves a paginated list of invitees associated with a Grammarly institution. Each invitee object in the response includes the invitee ID, institution ID, email, name, admin identifier, status, and creation timestamp.

Request Parameters

ParameterTypeRequiredDescription
limitIntegerNoSpecifies the maximum number of invitees' records to return per request. The minimum possible value is 1, while the maximum is 250. If the parameter is missing, it will default to 100.
cursorStringNoSpecifies the starting point of the records to return, enabling pagination. When it’s not passed, the API will return the first set of invitees. The value in the returned next_cursor should be set to this cursor value to get the next page set.

Example Request

An example cURL request to get the first ten invitees:

bash
curl -X GET \ 
  'https://api.grammarly.com/ecosystem/api/v1/invitees?limit=10&cursor=XaB4' \ 
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response Format

The response is a JSON object that includes an array of invitee objects and a paging containing information about the data returned.

Response Parameters

ParameterTypeDescription
dataArrayAn array of invitee objects containing invitee details (described below).
pagingObjectAn object containing information about the returned response (described below).

Each invitee object in the data array has the following structure:

FieldTypeDescription
idIntegerA unique identifier for the invitee.
institution_idIntegerThe ID of the institution the invitee is associated with.
emailStringThe invitee’s email address.
nameStringThe full name of the invitee.
created_atStringTimestamp of the invitee’s creation time in ISO 8601.
is_adminBooleanA boolean to identify if that invitee is an admin or not.
statusStringEither INVITED or EXPIRED. The INVITED has a valid invite and can join the institution. The EXPIRED invitee has to be reinvited by the admin to be able to join and become a user. Note that an expired invitee still occupies a license until removed.

The paging object has the following structure:

FieldTypeDescription
next_cursorStringSet to the cursor that can be used to get the next set of invitees. It will not be available if no more data exists (reflected also in has_more below).
cur_cursorStringSet to the cursor passed in the request or not available if nothing existed.
has_moreBooleanSet to true if more data exists and can be requested.
page_sizeIntegerThe total number of elements in the data array above.

Example Response

An example response body:

json
{
  "data": [
    {
      "id": 1234567890,
      "institution_id": 6123456789,
      "email": "john.doe@grammarly.com",
      "name": "John Doe",
      "created_at": "2023-05-16T18:19:36Z",
      "status": "EXPIRED",
      "is_admin": true
    },
    {
      "id": 1234567891,
      "institution_id": 6123456789,
      "email": "Jane.Doe@grammarly.com",
      "name": "Jane Doe",
      "created_at": "2023-05-16T18:21:02Z",
      "status": "INVITED",
      "is_admin": false
    }
  ],
  "paging": {
    "next_cursor": "MTYzNTc5NDQ1",
    "cur_cursor": "OTIyNzQ3OTM=",
    "has_more": true,
    "page_size": 2
  }
}

Usage Notes

Use limit and cursor parameters to manage pagination through the invitees list.

The created_at field helps to identify when the invitee was invited and is formatted in UTC.

Remove the invitee from the institution

DELETE https://api.grammarly.com/ecosystem/api/v1/invitees/{inviteeId}

This endpoint deletes a specified invitee from the Institution by their unique invitee ID.

Request Parameters

ParameterTypeRequiredDescription
inviteeIdIntegerYesThe unique identifier of the invitee to delete.

Example Request

An example cURL request to delete an invitee:

bash
curl -X DELETE \ 
  'https://api.grammarly.com/ecosystem/api/v1/invitees/1234567890' \ 
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response Format

A successful response typically contains a status code indicating the invitee was deleted. If the invitee was not found or the deletion failed, an error response is returned.

Successful Response (204 No Content)

If the deletion is successful, the server will return a 204 No Content response, indicating that the invitee was deleted successfully and no content is returned in the body.

Error Responses

Status CodeDescription
403Insufficient permissions to delete the user.
404The invitee with the specified ID was not found.
500Server error during deletion.

Getting the institution summary

GET https://api.grammarly.com/ecosystem/api/v1/institutions-summary

This endpoint gets an overview of the institution.

Example Request

An example cURL request to get a summary for an institution:

bash
curl -X GET \ 
  'https://api.grammarly.com/ecosystem/api/institutions-summary' \ 
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response Format

The response is a JSON object that includes an object containing the requested info.

Response Parameters

FieldTypeDescription
idIntegerThe institution ID.
nameStringThe name of the institution.
seatsIntegerThe total number of licenses in this subscription.
enrolledIntegerThe number of users who joined your Grammarly institution.
expiration_dateStringThe expiration date of the subscription is in ISO 8601 date format.
user_typesObjectAn object specifying the types of current users (described below)

The user_types object has the following structure:

FieldTypeDescription
adminsIntegerThe number of admins in this institution.
activeIntegerThe number of active users in this institution, excluding admins.
invitedIntegerThe number of active or expired invitees. Removed invitees are omitted here.
removedIntegerThe number of removed users and invitees (those users that were added and then removed for any reason, and invitees that were invited and then removed before accepting the invitation).
overage_seatsIntegerIt indicates the number of occupied seats that exceed those paid for in the subscription: admins + active + invited - seats.

Example Response

An example response body:

json
{
  "id": 6123456789,
  "name": "Integration Business",
  "seats": 15,
  "enrolled": 4,
  "expiration_date": "2023-05-03",
  "user_types": {
    "removed": 2,
    "invited": 3,
    "admins": 3,
    "active": 1
  }
}

Usage Notes

The parameters in the user_types object will only be returned if they’re > 0.

Constraints

Max Request Rates

Consider exponential backoff to handle requests with status code 429. Load test results indicate an ideal base factor of 2 seconds.

50 requests per second. The maximum number of requests per endpoint.