RequestRocketRequestRocketDocs
API ReferenceMSP API

Members & Invites

Manage your MSP team members and send invitations to new members

Members & Invites

Manage the members of your MSP team and send invitations to onboard new members.

To add a new user to your MSP team, use the Invites endpoints to send an email invitation. The user accepts the invite from their account and is automatically added with the specified roles.

Member Endpoints

MethodEndpointDescriptionMin Role
GET/api/msps/{mspId}/membersList all MSP team membersmsp_reader
GET/api/msps/{mspId}/members/{userId}Get a specific team membermsp_reader
PUT/api/msps/{mspId}/members/{userId}Update a member's rolesmsp_admin
DELETE/api/msps/{mspId}/members/{userId}Remove a member from the MSPmsp_admin

Invite Endpoints

MethodEndpointDescriptionMin Role
GET/api/msps/{mspId}/invitesList all pending invitesmsp_admin
POST/api/msps/{mspId}/invitesSend a new invitationmsp_admin
PUT/api/msps/{mspId}/invites/{inviteId}Update roles or re-issue an invitemsp_admin
DELETE/api/msps/{mspId}/invites/{inviteId}Cancel a pending invitemsp_admin

List Members

Retrieve all members of your MSP team.

Request

GET /api/msps/{mspId}/members HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}

Response

{
  "members": [
    {
      "userId": "123e4567-e89b-12d3-a456-426614174000",
      "roles": ["msp_owner"],
      "userEmail": "alice@example.com",
      "userFirstName": "Alice",
      "userLastName": "Smith",
      "userCreated": "2024-01-10T08:00:00.000Z",
      "userUpdated": "2024-01-20T10:30:00.000Z"
    },
    {
      "userId": "223e4567-e89b-12d3-a456-426614174001",
      "roles": ["msp_admin"],
      "userEmail": "bob@example.com",
      "userFirstName": "Bob",
      "userLastName": "Johnson",
      "userCreated": "2024-02-01T09:00:00.000Z",
      "userUpdated": "2024-02-10T11:20:00.000Z"
    }
  ],
  "message": "Success"
}

Example

curl -X GET "https://api.requestrocket.com/api/msps/${MSP_ID}/members" \
  -H "Authorization: ${USER_TOKEN}"
const response = await fetch(
  `https://api.requestrocket.com/api/msps/${mspId}/members`,
  {
    headers: { 'Authorization': process.env.USER_TOKEN }
  }
);
const data = await response.json();
console.log('Team members:', data.members);
import requests, os

response = requests.get(
    f'https://api.requestrocket.com/api/msps/{msp_id}/members',
    headers={'Authorization': os.getenv('USER_TOKEN')}
)
print(response.json()['members'])
req, _ := http.NewRequest("GET",
    fmt.Sprintf("https://api.requestrocket.com/api/msps/%s/members", mspId), nil)
req.Header.Set("Authorization", os.Getenv("USER_TOKEN"))

resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.requestrocket.com/api/msps/" + mspId + "/members"))
    .header("Authorization", System.getenv("USER_TOKEN"))
    .GET()
    .build();
HttpResponse<String> response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Update Member Roles

Change the roles assigned to a team member.

  • The last msp_owner cannot have their owner role removed
  • The last msp_admin cannot have their admin role removed
  • Both protections apply to the member being edited, not the requestor

Request

PUT /api/msps/{mspId}/members/{userId} HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}
Content-Type: application/json

{
  "roles": ["msp_admin"]
}

Request Body

FieldTypeRequiredDescription
rolesstring[]YesOne or more roles to assign. Valid values: msp_owner, msp_admin, msp_user, msp_reader

Response

{
  "members": [
    {
      "userId": "223e4567-e89b-12d3-a456-426614174001",
      "roles": ["msp_admin"]
    }
  ],
  "message": "Member roles updated"
}

Example

curl -X PUT "https://api.requestrocket.com/api/msps/${MSP_ID}/members/${USER_ID}" \
  -H "Authorization: ${USER_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"roles": ["msp_admin"]}'
const response = await fetch(
  `https://api.requestrocket.com/api/msps/${mspId}/members/${userId}`,
  {
    method: 'PUT',
    headers: {
      'Authorization': process.env.USER_TOKEN,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ roles: ['msp_admin'] })
  }
);
const data = await response.json();
console.log('Updated roles:', data.members[0].roles);
import requests, os

response = requests.put(
    f'https://api.requestrocket.com/api/msps/{msp_id}/members/{user_id}',
    headers={'Authorization': os.getenv('USER_TOKEN')},
    json={'roles': ['msp_admin']}
)
print(response.json())
body := bytes.NewBufferString(`{"roles":["msp_admin"]}`)
req, _ := http.NewRequest("PUT",
    fmt.Sprintf("https://api.requestrocket.com/api/msps/%s/members/%s", mspId, userId), body)
req.Header.Set("Authorization", os.Getenv("USER_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
String json = "{\"roles\": [\"msp_admin\"]}";
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.requestrocket.com/api/msps/" + mspId + "/members/" + userId))
    .header("Authorization", System.getenv("USER_TOKEN"))
    .header("Content-Type", "application/json")
    .PUT(HttpRequest.BodyPublishers.ofString(json))
    .build();
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

Remove Member

Remove a user from your MSP team. Their userMsps list is updated automatically.

You cannot remove the last msp_owner or the last msp_admin.

Request

DELETE /api/msps/{mspId}/members/{userId} HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}

Response

{
  "message": "Member removed from MSP"
}

Example

curl -X DELETE "https://api.requestrocket.com/api/msps/${MSP_ID}/members/${USER_ID}" \
  -H "Authorization: ${USER_TOKEN}"
const response = await fetch(
  `https://api.requestrocket.com/api/msps/${mspId}/members/${userId}`,
  { method: 'DELETE', headers: { 'Authorization': process.env.USER_TOKEN } }
);
const data = await response.json();
console.log(data.message);
import requests, os

response = requests.delete(
    f'https://api.requestrocket.com/api/msps/{msp_id}/members/{user_id}',
    headers={'Authorization': os.getenv('USER_TOKEN')}
)
print(response.json()['message'])
req, _ := http.NewRequest("DELETE",
    fmt.Sprintf("https://api.requestrocket.com/api/msps/%s/members/%s", mspId, userId), nil)
req.Header.Set("Authorization", os.Getenv("USER_TOKEN"))
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.requestrocket.com/api/msps/" + mspId + "/members/" + userId))
    .header("Authorization", System.getenv("USER_TOKEN"))
    .DELETE()
    .build();
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

Send Invite

Invite a new user to join your MSP team by email. If the email matches an existing RequestRocket account, the invite is linked to that user. If no account exists, the user can sign up and then accept the invite.

Request

POST /api/msps/{mspId}/invites HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}
Content-Type: application/json

{
  "userEmail": "newmember@example.com",
  "roles": ["msp_user"]
}

Request Body

FieldTypeRequiredDescription
userEmailstringYesEmail address of the person to invite
rolesstring[]YesRoles to assign on acceptance. Valid values: msp_owner, msp_admin, msp_user, msp_reader

Response

{
  "invites": [
    {
      "inviteId": "abc12345-e89b-12d3-a456-426614174000",
      "userEmail": "newmember@example.com",
      "roles": ["msp_user"],
      "inviteExpiry": "2024-03-01T00:00:00.000Z",
      "inviteCreated": "2024-02-15T10:00:00.000Z"
    }
  ],
  "message": "Invite created"
}

Example

curl -X POST "https://api.requestrocket.com/api/msps/${MSP_ID}/invites" \
  -H "Authorization: ${USER_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "userEmail": "newmember@example.com",
    "roles": ["msp_user"]
  }'
const response = await fetch(
  `https://api.requestrocket.com/api/msps/${mspId}/invites`,
  {
    method: 'POST',
    headers: {
      'Authorization': process.env.USER_TOKEN,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      userEmail: 'newmember@example.com',
      roles: ['msp_user']
    })
  }
);
const data = await response.json();
console.log('Invite created:', data.invites[0].inviteId);
import requests, os

response = requests.post(
    f'https://api.requestrocket.com/api/msps/{msp_id}/invites',
    headers={'Authorization': os.getenv('USER_TOKEN')},
    json={'userEmail': 'newmember@example.com', 'roles': ['msp_user']}
)
print(response.json())
body := bytes.NewBufferString(`{"userEmail":"newmember@example.com","roles":["msp_user"]}`)
req, _ := http.NewRequest("POST",
    fmt.Sprintf("https://api.requestrocket.com/api/msps/%s/invites", mspId), body)
req.Header.Set("Authorization", os.Getenv("USER_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
String json = "{\"userEmail\":\"newmember@example.com\",\"roles\":[\"msp_user\"]}";
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.requestrocket.com/api/msps/" + mspId + "/invites"))
    .header("Authorization", System.getenv("USER_TOKEN"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .build();
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

Update Invite

Update the roles on a pending invite and extend its expiry by 14 days, effectively re-issuing it.

Request

PUT /api/msps/{mspId}/invites/{inviteId} HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}
Content-Type: application/json

{
  "roles": ["msp_admin"]
}

Request Body

FieldTypeRequiredDescription
rolesstring[]YesUpdated roles to assign on acceptance

Response

{
  "invites": [
    {
      "inviteId": "abc12345-e89b-12d3-a456-426614174000",
      "userEmail": "newmember@example.com",
      "roles": ["msp_admin"],
      "inviteExpiry": "2024-03-15T00:00:00.000Z",
      "inviteUpdated": "2024-03-01T10:00:00.000Z"
    }
  ],
  "message": "Invite updated"
}

Cancel Invite

Revoke a pending invite. The invitation link will no longer be valid.

Request

DELETE /api/msps/{mspId}/invites/{inviteId} HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}

Response

{
  "message": "Invite deleted"
}

Example

curl -X DELETE "https://api.requestrocket.com/api/msps/${MSP_ID}/invites/${INVITE_ID}" \
  -H "Authorization: ${USER_TOKEN}"
const response = await fetch(
  `https://api.requestrocket.com/api/msps/${mspId}/invites/${inviteId}`,
  { method: 'DELETE', headers: { 'Authorization': process.env.USER_TOKEN } }
);
const data = await response.json();
console.log(data.message);
import requests, os

response = requests.delete(
    f'https://api.requestrocket.com/api/msps/{msp_id}/invites/{invite_id}',
    headers={'Authorization': os.getenv('USER_TOKEN')}
)
print(response.json()['message'])
req, _ := http.NewRequest("DELETE",
    fmt.Sprintf("https://api.requestrocket.com/api/msps/%s/invites/%s", mspId, inviteId), nil)
req.Header.Set("Authorization", os.Getenv("USER_TOKEN"))
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.requestrocket.com/api/msps/" + mspId + "/invites/" + inviteId))
    .header("Authorization", System.getenv("USER_TOKEN"))
    .DELETE()
    .build();
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

Error Responses

StatusMessageCause
400Roles requiredNo roles provided in the request body
400Input failed data validationInvalid role value or malformed body
404Member not found in MSPThe userId is not a member of this MSP
400Cannot remove last msp_ownerRemoving the sole owner is not permitted
400Cannot remove last msp_adminRemoving the sole admin is not permitted
409Invite already exists for this emailA pending invite for this email already exists — use PUT to re-issue

Next Steps

On this page