MSP

The MSP (Managed Service Provider) Public API enables resellers to manage webhooks for events occurring in the Egnyte Reseller Dashboard (MSP Portal) and also fetch data for the plans and domains as visible in the UI.

Note: This API is available only to approved MSP partners.

Base URL

https://{demo_domain}.egnyte.com/puboauth/token

Prerequisites

Before using the MSP API, ensure you have:

  • Active developer account — Register for a developer account if you don't have one already
  • Active Demo domain — A Not-For-Resale domain for testing
  • Active user on Demo domain — A user account on your Demo domain
  • Active MSP Portal user — A user on the MSP Portal with the same email address as your Demo domain user
  • API Key (Client ID) — Provided during developer account registration

Developer Account Registration

If you don't have a developer account, register here. When registering, use these settings:

FieldValue
EmailUse the same email address registered in the reseller portal registration
TypeSelect "Publicly Available Application"
Egnyte domain you will use for testingYour Demo domain name
Registered OAuth Redirect URIhttps://resellers.egnyte.com/accounts/login/
Web APIsCheck "Issue a new key for Egnyte Connect API"Uncheck "Issue a new key for Egnyte S&G"

Authentication

The MSP API uses OAuth 2.0 Implicit Grant flow. This flow issues access tokens directly without requiring a client secret, making it suitable for applications that cannot securely store secrets.

Warning: Store access tokens encrypted. Never store tokens in browser localStorage or expose them in client-side code.

Implicit Grant Flow

The Implicit Grant flow consists of two steps:

  1. Initiate the authentication flow
  2. Extract the access token from the response

Step 1: Initiate Authentication

Direct the user to the following authorization URL:

https://{demo_domain}.egnyte.com/puboauth/token?client_id={api_key}&redirect_uri=https://resellers.egnyte.com/accounts/login/&response_type=token

Parameters

ParameterTypeRequiredDescription
demo_domainstringYesYour Demo domain name (without .egnyte.com)
client_idstringYesYour API key provided during registration
redirect_uristringYesMust be https://resellers.egnyte.com/accounts/login/
response_typestringYesMust be token for Implicit Grant flow

Example Request

https://{demo_domain}.egnyte.com/puboauth/token?client_id=x2g35g8gynb5cedas649m4h4&redirect_uri=https://resellers.egnyte.com/accounts/login/&response_type=token

The user will be redirected to an authorization page where they must:

  1. Review the permissions your application is requesting
  2. Enter their login credentials
  3. Authorize your application to access their account

Step 2: Extract Access Token

Success Response

If the user authorizes your application, they are redirected to:

https://resellers.egnyte.com/accounts/login/#access_token={oauth_token}&token_type=bearer

Extract the access_token value from the URL fragment. This token is used for all subsequent API requests.

Example Success URL

https://resellers.egnyte.com/accounts/login/#access_token=2v8q2bc6uvxtgghwmwvnvcp4&token_type=bearer

Denial Response

If the user denies authorization, they are redirected to:

https://resellers.egnyte.com/accounts/login/#error=access_denied

Using the Access Token

Include the access token in the Authorization header of all API requests:

Authorization: Bearer {access_token}

Example

curl -i -X GET "https://{demo_domain}.egnyte.com/pubapi/v1/msp/webhooks" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Token Lifecycle

  • Expiration: Bearer tokens issued by the MSP API do not expire automatically
  • Invalidation: Tokens become invalid when:
    • The user changes their password
    • The user explicitly revokes access to your application
    • An administrator revokes the user's permissions

Note: Cache and reuse access tokens rather than requesting new tokens for each API call. Treat tokens with the same security as passwords.

Handling Authentication Failures

Your application must handle 401 Unauthorized responses by re-initiating the OAuth flow to obtain a new token.

Error Codes

StatusErrorDescriptionResolution
401UnauthorizedInvalid or revoked access tokenRe-initiate OAuth flow to obtain a new token
403ForbiddenWhen any of the pre-requisites are not met like MSP user is not active, or user on Demo domain is not activeVerify that all pre-requisites are met
404Not FoundWebhook or resource does not existVerify the resource ID and ensure it hasn't been deleted
429Rate LimitedToo many requestsImplement exponential backoff; check Retry-After header

Webhooks

This is a set of endpoints to manage webhooks. The number of webhooks registered for one pair: clientId+NFRDomain is limited.

List Webhooks

Returns all webhooks registered by the MSP.

GET /pubapi/v1/msp/webhooks

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/webhooks" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

[
  { "status": "enabled", "webhook_id": "4091c6d2-1bce-4df8-a119-a7bcb9b8474c" },
  { "status": "enabled", "webhook_id": "656bc761-9454-464c-adff-457691b5effa" }
]
FieldTypeDescription
webhook_idstring (UUID)Webhook identifier
statusstringenabled or disabled

Register a Webhook

Registers a new webhook. The number of webhooks per clientId + NFR domain pair is limited. For webhook payload documentation see Webhook Receiver Specification.

POST /pubapi/v1/msp/webhooks

Request Body

FieldTypeRequiredDescription
webhook_urlstringYesHTTPS URL to receive webhook payloads
eventTypesarrayYesOne or more event type strings (see Event Types)
auth_headerstringYesName of the auth header sent with each payload
auth_header_valuestringYesValue of the auth header

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/msp/webhooks" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "webhook_url": "https://www.example.com/egnyte-events",
  "eventTypes": [
    "RESELLER_CREATED_CONNECT_TRIAL",
    "RESELLER_CONVERTED_CONNECT_TRIAL_TO_PAID"
  ],
  "auth_header": "AUTH-TOKEN",
  "auth_header_value": "XYZ"
}'

200 OK

{
  "status": "enabled",
  "webhook_id": "a63790bf-2847-4abd-a0cb-3a06c3958659"
}

400 Bad Request

CodeDescription
unknown_event_typesOne or more event type strings are invalid
non_https_webhook_urlWebhook URL must use HTTPS
request_schema_errorauth_header or auth_header_value is blank

409 Conflict

{ "message": "Max webhook limit exceeded.", "code": "webhook_limit_exceeded_error" }

Get Webhook Details

Returns details of a single webhook.

GET /pubapi/v1/msp/webhooks/{webhook_id}

Path Parameters

ParameterTypeRequiredDescription
webhook_idstring (UUID)YesWebhook identifier

200 OK

{
  "webhook_id": "e4bf314d-4657-483a-a2b2-db1eda8c9509",
  "event_types": ["RESELLER_LINK_NFR_MANUALLY", "RESELLER_CREATED_CONNECT_TRIAL"],
  "webhook_url": "https://www.example.com/egnyte-events-2",
  "auth_header": "X-TOKEN",
  "auth_header_value": "a234fsd34fsdf4eghujj68",
  "status": "enabled"
}
FieldTypeDescription
webhook_idstring (UUID)Webhook identifier
webhook_urlstringRegistered HTTPS URL
event_typesarraySubscribed event types
auth_headerstringAuth header name
auth_header_valuestringAuth header value
statusstringenabled or disabled

404 Not Found

{ "message": "Webhook not found. Please check the webhook id e4bf314d-...", "code": "webhook_not_found_error" }

Update a Webhook

Updates an existing webhook. Replaces all fields.

PUT /pubapi/v1/msp/webhooks/{webhook_id}

Path Parameters

ParameterTypeRequiredDescription
webhook_idstring (UUID)YesWebhook identifier

Request Body

Same fields as Register a Webhook.

Example Request

curl -i -X PUT "https://{domain}.egnyte.com/pubapi/v1/msp/webhooks/{webhook_id}" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "webhook_url": "https://www.example.com/egnyte-events-updated",
  "eventTypes": [
    "RESELLER_MRR_CHANGED"
  ],
  "auth_header": "AUTH-TOKEN",
  "auth_header_value": "NEW-VALUE"
}'

200 OK

{ "status": "enabled", "webhook_id": "{webhook_id}" }

400 Bad Request — Same error codes as Register a Webhook.


Delete a Webhook

Unregisters a webhook.

DELETE /pubapi/v1/msp/webhooks/{webhook_id}

Path Parameters

ParameterTypeRequiredDescription
webhook_idstring (UUID)YesWebhook identifier

Example Request

curl -i -X DELETE "https://{domain}.egnyte.com/pubapi/v1/msp/webhooks/{webhook_id}" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{ "success": true }

404 Not Found

{ "message": "Webhook not found. Please check the webhook id e4bf314d-...", "code": "webhook_not_found_error" }

Event Types

The following event type strings are supported for webhook subscriptions:

Event TypeDescription
RESELLER_LINK_NFR_MANUALLYNFR domain linked manually to reseller
RESELLER_CREATED_CONNECT_TRIALReseller created a Connect trial
RESELLER_CREATED_PROTECT_TRIALReseller created a Protect trial
RESELLER_CONVERTED_CONNECT_TRIAL_TO_PAIDConnect trial converted to paid
RESELLER_CONVERTED_PROTECT_TRIAL_TO_PAIDProtect trial converted to paid
RESELLER_CONNECT_TRIAL_EXPIREDConnect trial expired
RESELLER_PROFILE_UPDATEDReseller profile updated
RESELLER_MRR_CHANGEDReseller monthly recurring revenue changed
RESELLER_FIRST_LOGINReseller first login
RESELLER_CC_ADDEDCredit card added
RESELLER_PVI_ADDEDPVI added
USER_ADDEDUser added
RESELLER_TFA_ENABLEDTwo-factor auth enabled for reseller
RESELLER_TFA_ENROLLEDTwo-factor auth enrolled for reseller
USER_TFA_ENABLEDTwo-factor auth enabled for user
USER_TFA_ENROLLEDTwo-factor auth enrolled for user
RESELLER_UPSELL_INVOICE_GENERATEDUpsell invoice generated
RESELLER_RECURRING_INVOICE_GENERATEDRecurring invoice generated
RESELLER_INVOICE_EDITEDInvoice edited
RESELLER_INVOICE_PAIDInvoice paid
RESELLER_PU_PURCHASEDPower users purchased for MSP pool

Webhook Receiver Specification

The Webhook Receiver endpoint accepts POST requests with contents of an MSP event.

Your server implementation should return HTTP status code 200 if the data was received and should not be retransmitted. Non-200 status codes will schedule a retransmission and eventually cause the webhook to be disabled.

(re)Transmission Policy

If sending a webhook call fails due to network issues or the receiver responds with a status other than 200, the request will be retried in the next schedule. Permanent delivery failure despite multiple retries is counted. Multiple permanent delivery failures will result in the webhook being disabled.

Common Fields

All event payloads include these base fields:

FieldTypeDescription
event_typestringEvent type identifier (see Event Types)
reseller_codestringUnique alphanumeric code identifying the reseller
first_namestringReseller's first name
last_namestringReseller's last name
emailstringReseller account's primary email
company_namestringReseller's company name
transaction_timestampstring (ISO 8601)When the event occurred
event_created_bystringName of the user who triggered the event
is_event_by_staff_userbooleantrue if triggered by an Egnyte staff member

Event Types and Additional Fields


RESELLER_LINK_NFR_MANUALLY

NFR (Not-For-Resale) demo domain linked to the reseller.

FieldTypeDescription
nfr_domain_namestringName of the NFR domain linked
nfr_planstringPlan deployed on the NFR domain
power_usersintegerNumber of power user licenses on the NFR domain
storageintegerStorage allocated on the NFR domain (GB)
{
  "event_type": "RESELLER_LINK_NFR_MANUALLY",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "nfr_domain_name": "acmedemo",
  "nfr_plan": "Business",
  "power_users": 25,
  "storage": 200
}

RESELLER_CREATED_CONNECT_TRIAL

Reseller created a new Connect trial domain.

FieldTypeDescription
domainstringName of the newly created trial domain
power_usersintegerNumber of power user licenses
storageintegerStorage allocated (GB)
pviintegerPlan ID
plan_namestringPlan name
{
  "event_type": "RESELLER_CREATED_CONNECT_TRIAL",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "domain": "acmetrial",
  "power_users": 10,
  "storage": 100,
  "pvi": 42,
  "plan_name": "Business"
}

RESELLER_CREATED_PROTECT_TRIAL

Reseller created a new Protect trial account.

FieldTypeDescription
domainstringName of the newly created trial account
power_usersintegerNumber of power user licenses
pviintegerPlan ID (optional)
plan_namestringPlan name
tenant_idstring (UUID)Unique identifier for the Protect tenant
{
  "event_type": "RESELLER_CREATED_PROTECT_TRIAL",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "domain": "acmeprotect",
  "power_users": 10,
  "plan_name": "Protect",
  "tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

RESELLER_CONVERTED_CONNECT_TRIAL_TO_PAID

Connect trial domain converted to a paid subscription.

FieldTypeDescription
domainstringName of the converted domain
power_usersintegerNumber of power user licenses
storageintegerStorage allocated (GB)
pviintegerPlan ID
plan_namestringPlan name
{
  "event_type": "RESELLER_CONVERTED_CONNECT_TRIAL_TO_PAID",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "domain": "acmetrial",
  "power_users": 25,
  "storage": 500,
  "pvi": 42,
  "plan_name": "Business"
}

RESELLER_CONVERTED_PROTECT_TRIAL_TO_PAID

Protect trial account converted to a paid subscription.

FieldTypeDescription
domainstringName of the converted account
power_usersintegerNumber of power user licenses
pviintegerPlan ID (optional)
plan_namestringPlan name
tenant_idstring (UUID)Unique identifier for the Protect tenant
{
  "event_type": "RESELLER_CONVERTED_PROTECT_TRIAL_TO_PAID",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "domain": "acmeprotect",
  "power_users": 25,
  "plan_name": "Protect",
  "tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

RESELLER_CONNECT_TRIAL_EXPIRED

Connect trial domain expired without conversion.

FieldTypeDescription
domainstringName of the expired trial domain
power_usersintegerNumber of power user licenses
storageintegerStorage allocated (GB)
pviintegerPlan ID
plan_namestringPlan name
{
  "event_type": "RESELLER_CONNECT_TRIAL_EXPIRED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "domain": "acmetrial",
  "power_users": 10,
  "storage": 100,
  "pvi": 42,
  "plan_name": "Business"
}

RESELLER_PROFILE_UPDATED

Reseller profile field was updated.

FieldTypeDescription
field_namestringName of the updated field
old_valuestringPrevious value
new_valuestringNew value
{
  "event_type": "RESELLER_PROFILE_UPDATED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "field_name": "company_name",
  "old_value": "Acme Corp",
  "new_value": "Acme Corporation"
}

RESELLER_MRR_CHANGED

Monthly recurring revenue changed for the reseller.

FieldTypeDescription
reasonstringReason for the MRR change
domainstringDomain name (null if domain-level consumption is not enabled)
plansarrayList of plans affected by the change
delta_mrrnumberChange in monthly cost
delta_quantityintegerChange in power users or storage (null for OPTIONAL_FEATURE_PURCHASE and SUPPORT_LEVEL_CHANGE)
optional_feature_namestringName of the optional feature enabled/disabled (null for other reasons)
{
  "event_type": "RESELLER_MRR_CHANGED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "reason": "POWER_USER_PURCHASE",
  "domain": "acmecorp",
  "plans": ["Business"],
  "delta_mrr": 15.00,
  "delta_quantity": 5,
  "optional_feature_name": null
}

RESELLER_FIRST_LOGIN

Reseller logged in to the MSP Portal for the first time.

FieldTypeDescription
first_login_datetimestring (ISO 8601)Timestamp of first login
{
  "event_type": "RESELLER_FIRST_LOGIN",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "first_login_datetime": "2026-07-21T10:30:00Z"
}

RESELLER_CC_ADDED

Credit card added to the reseller account.

FieldTypeDescription
cc_numberstringLast 4 digits of the credit card
usaepay_idstringPayment reference ID
{
  "event_type": "RESELLER_CC_ADDED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "cc_number": "4242",
  "usaepay_id": "ref-98765"
}

RESELLER_PVI_ADDED

Plans added to the reseller account.

FieldTypeDescription
plansarrayList of plans added
{
  "event_type": "RESELLER_PVI_ADDED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "plans": ["Business", "Enterprise"]
}

USER_ADDED

New user added to the MSP Portal.

FieldTypeDescription
user_usernamestringUsername of the new user
user_first_namestringFirst name of the new user
user_last_namestringLast name of the new user
user_typestringUser type (e.g. Administrator, IT Admin)
{
  "event_type": "USER_ADDED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "user_username": "john.smith",
  "user_first_name": "John",
  "user_last_name": "Smith",
  "user_type": "IT Admin"
}

RESELLER_TFA_ENABLED

Two-factor authentication enabled at the reseller account level. No additional fields beyond common fields.

{
  "event_type": "RESELLER_TFA_ENABLED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false
}

RESELLER_TFA_ENROLLED

Reseller enrolled in two-factor authentication. No additional fields beyond common fields.

{
  "event_type": "RESELLER_TFA_ENROLLED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false
}

USER_TFA_ENABLED

Two-factor authentication enabled for a specific MSP Portal user. No additional fields beyond common fields.

{
  "event_type": "USER_TFA_ENABLED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false
}

USER_TFA_ENROLLED

MSP Portal user enrolled in two-factor authentication.

FieldTypeDescription
user_usernamestringUsername of the user who enrolled
user_first_namestringFirst name of the user
user_last_namestringLast name of the user
user_typestringUser type
{
  "event_type": "USER_TFA_ENROLLED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "user_username": "john.smith",
  "user_first_name": "John",
  "user_last_name": "Smith",
  "user_type": "IT Admin"
}

RESELLER_UPSELL_INVOICE_GENERATED

Upsell invoice generated for the reseller.

FieldTypeDescription
invoice_idintegerInvoice ID
amountnumberTotal invoice amount
tax_amountnumberTotal tax amount
invoice_periodstringInvoice generation schedule
{
  "event_type": "RESELLER_UPSELL_INVOICE_GENERATED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "invoice_id": 10042,
  "amount": 150.00,
  "tax_amount": 12.50,
  "invoice_period": "monthly"
}

RESELLER_RECURRING_INVOICE_GENERATED

Recurring invoice generated for the reseller.

FieldTypeDescription
invoice_idintegerInvoice ID
amountnumberTotal invoice amount
tax_amountnumberTotal tax amount
invoice_periodstringInvoice generation schedule
{
  "event_type": "RESELLER_RECURRING_INVOICE_GENERATED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "invoice_id": 10043,
  "amount": 500.00,
  "tax_amount": 41.25,
  "invoice_period": "monthly"
}

RESELLER_INVOICE_EDITED

Existing invoice was edited.

FieldTypeDescription
invoice_idintegerInvoice ID
amountnumberUpdated total invoice amount
tax_amountnumberUpdated total tax amount
invoice_periodstringInvoice generation schedule
delta_invoice_amountnumberChange in invoice amount
{
  "event_type": "RESELLER_INVOICE_EDITED",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": true,
  "invoice_id": 10043,
  "amount": 480.00,
  "tax_amount": 39.60,
  "invoice_period": "monthly",
  "delta_invoice_amount": -20.00
}

RESELLER_INVOICE_PAID

Invoice payment received.

FieldTypeDescription
payment_ref_numberstringReference number of the paid invoice
invoice_initiatorstringWhether payment was automatic (credit card) or manual
payment_modestringPayment mode selected in the reseller portal
{
  "event_type": "RESELLER_INVOICE_PAID",
  "reseller_code": "msp10reseller",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane.doe@example.com",
  "company_name": "Acme Corp",
  "transaction_timestamp": "2026-07-21T10:30:00Z",
  "event_created_by": "Jane Doe",
  "is_event_by_staff_user": false,
  "payment_ref_number": "INV-10043",
  "invoice_initiator": "automatic",
  "payment_mode": "Credit Card"
}

Domains

This is a set of endpoints to manage domains.

List Domains

Returns a paginated list of domains registered by the MSP.

GET /pubapi/v1/msp/domains

Query Parameters

ParameterTypeRequiredDescription
planNamestringNoFilter domains by plan name

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/domains" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "next": null,
  "previous": null,
  "count": 10,
  "results": [
    {
      "domain": "testDomain",
      "planId": 1,
      "planName": "Platform Enterprise",
      "status": "active",
      "createdOn": "2024-03-28T00:00:00",
      "subscriptionDate": "2024-03-23",
      "availablePuLicences": 10,
      "usedPuLicences": 1,
      "unusedPuLicences": 9,
      "availableSuLicences": 10,
      "usedSuLicences": 0,
      "unusedSuLicences": 10,
      "availableStorage": 2000,
      "usedStorage": 0,
      "allocatedStorage": 1000
    }
  ]
}
FieldTypeDescription
nextstring | nullURL to the next page of results
previousstring | nullURL to the previous page of results
countintegerTotal number of domains
resultsarrayList of domain objects (see Get Domain Details for field descriptions)

Get Domain Details

Returns details for a specific domain.

GET /pubapi/v1/msp/domains/{domain}

Path Parameters

ParameterTypeRequiredDescription
domainstringYesDomain name

Example Request

curl -i -X GET "https://{egnyte_domain}.egnyte.com/pubapi/v1/msp/domains/{domain}" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "domain": "testDomain",
  "planId": 1,
  "planName": "Platform Enterprise",
  "status": "active",
  "createdOn": "2024-03-19T00:00:00",
  "subscriptionDate": "2024-03-19",
  "availablePuLicences": 3,
  "usedPuLicences": 1,
  "unusedPuLicences": 2,
  "availableSuLicences": 3,
  "usedSuLicences": 1,
  "unusedSuLicences": 2,
  "availableStorage": 1000,
  "usedStorage": 0,
  "allocatedStorage": 10,
  "monthlyCost": 0,
  "features": [
    { "name": "olc", "title": "Turbo or Storage Sync", "category": "2 Free, Extra Optional", "type": "flat", "numPurchased": 2 }
  ],
  "sources": [
    { "name": "data_security_mgmt_gmail_users", "title": "Gmail Users", "category": "Optional", "type": "flat", "numPurchased": 0 }
  ]
}
FieldTypeDescription
domainstringDomain name
planIdintegerPlan identifier
planNamestringName of the plan
statusstringDomain status (e.g. active, trial)
createdOnstring (datetime)Domain creation timestamp
subscriptionDatestring (date)Subscription start date
availablePuLicencesintegerTotal power user licenses in pool
usedPuLicencesintegerPower user licenses in use
unusedPuLicencesintegerPower user licenses available
availableSuLicencesintegerTotal standard user licenses in pool
usedSuLicencesintegerStandard user licenses in use
unusedSuLicencesintegerStandard user licenses available
availableStorageintegerTotal storage in pool (GB)
usedStorageintegerStorage in use (GB)
allocatedStorageintegerStorage allocated to domain (GB)
monthlyCostnumberMonthly base cost
featuresarrayOptional features for the domain
sourcesarrayData sources for the domain

404 Not Found

{ "message": "Domain not found. Please check the domain id", "code": "domain_not_found_error" }

Tenants

Tenants represent Egnyte Protect subscriptions managed by the MSP.

List Tenants

Returns a paginated list of Protect tenants registered by the MSP.

GET /pubapi/v1/msp/tenants

Query Parameters

ParameterTypeRequiredDescription
planNamestringNoFilter tenants by plan name

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/tenants" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "next": null,
  "previous": null,
  "count": 3,
  "results": [
    {
      "tenant": "protecttestdomain1",
      "domain": "testdomain1",
      "planId": 20202,
      "planName": "Protect",
      "createdOn": "2024-05-08T00:00:00",
      "subscriptionDate": null,
      "status": "trial",
      "cupUsed": 69,
      "cupIncluded": 500,
      "totalCupPurchased": 10005,
      "totalCupIncluded": 1000,
      "totalCupAvailable": 11005,
      "totalCupUsed": 8669,
      "totalCupUnused": 2336
    }
  ]
}
FieldTypeDescription
tenantstringTenant name
domainstringAssociated domain name
planIdintegerPlan identifier
planNamestringName of the plan
createdOnstring (datetime)Tenant creation timestamp
subscriptionDatestring (date) | nullDate trial was activated; null if still trial
statusstringtrial or active
cupUsedintegerContent Under Protection used by tenant (GB)
cupIncludedintegerIncluded CUP available to tenant (GB)
totalCupPurchasedintegerAdditional CUP purchased by MSP (GB)
totalCupIncludedintegerTotal free CUP for all active tenants (GB)
totalCupAvailableintegerTotal CUP pool available to MSP (GB)
totalCupUsedintegerTotal CUP used across all tenants (GB)
totalCupUnusedintegerTotal unused CUP in MSP pool (GB)

Get Tenant Details

Returns details for a specific Protect tenant.

GET /pubapi/v1/msp/tenants/{tenant_name}

Path Parameters

ParameterTypeRequiredDescription
tenant_namestringYesTenant name

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/tenants/{tenant_name}" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "tenant": "protecttestdomain3",
  "domain": "testdomain3",
  "planId": 20202,
  "planName": "Protect",
  "createdOn": "2024-04-19T00:00:00",
  "subscriptionDate": "2024-04-24",
  "status": "active",
  "cupUsed": 8649,
  "cupIncluded": 500,
  "totalCupPurchased": 10005,
  "totalCupIncluded": 1000,
  "totalCupAvailable": 11005,
  "totalCupUsed": 8669,
  "totalCupUnused": 2336,
  "monthlyCost": 400.99
}

Same fields as List Tenants plus:

FieldTypeDescription
monthlyCostnumberMonthly base cost of the Protect plan

404 Not Found

{ "message": "Tenant not found. Please check the name of the tenant", "code": "tenant_not_found_error" }

Plans

This is a set of endpoints to manage plans.

List Plans

Returns a paginated list of plans available to the MSP.

GET /pubapi/v1/msp/plans

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/plans" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "next": null,
  "previous": null,
  "count": 10,
  "results": [
    {
      "id": 1,
      "planId": 10,
      "planName": "Example Plan",
      "maxPlanPuLicences": 5,
      "maxPlanSuLicences": 10,
      "costPerUser": 10,
      "maxPlanStorage": 10,
      "allocatedPlanStorage": 1,
      "availablePlanStorage": 9,
      "features": [{ "name": "example name", "type": "example type" }],
      "packages": [{ "name": "example name", "type": "example type" }],
      "sources": [{ "name": "example name", "type": "example type" }]
    }
  ]
}
FieldTypeDescription
idintegerPlan identifier used in trial creation
planIdintegerPlanset identifier (a planset contains multiple plans)
planNamestringName of the plan
maxPlanPuLicencesintegerTotal power user quota in plan (not returned for Protect plans)
maxPlanSuLicencesintegerTotal standard user quota in plan (not returned for Protect plans)
maxPlanStorageintegerTotal storage quota in plan (GB)
allocatedPlanStorageintegerStorage allocated across all domains (GB)
availablePlanStorageintegerStorage remaining in pool (GB)
costPerUserinteger | nullCost per user per month ($); only returned when DLC is enabled
featuresarrayFeatures available in the plan
packagesarrayPackages available in the plan
sourcesarraySources available in the plan
totalCupPurchasedintegerPurchased CUP (Protect plans only, GB)
totalCupIncludedintegerFree CUP (Protect plans only, GB)
totalCupAvailableintegerTotal CUP pool (Protect plans only, GB)
totalCupUsedintegerCUP used by tenants (Protect plans only, GB)
totalCupUnusedintegerUnused CUP (Protect plans only, GB)

Get Power Users Quote

Returns a pricing quote for adding power users to the MSP's pool without committing the purchase.

POST /pubapi/v1/msp/plans/{planId}/power-users/quote/

Path Parameters

ParameterTypeRequiredDescription
planIdstringYesPlan identifier

Request Body

FieldTypeRequiredConstraintsDescription
powerUsersintegerYesmin: 1Target number of power users (absolute count, not delta)

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/msp/plans/{planId}/power-users/quote/" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "powerUsers": 50
}'

200 OK

FieldTypeDescription
previousPowerUsersintegerCurrent power user count
newPowerUsersintegerPower user count after purchase
deltaPowerUsersintegerChange in power users
deltaMonthlystring (decimal)Change in monthly recurring cost ($)
proratedCoststring (decimal)Prorated charge for remainder of billing period ($)
proratedDaysLeftintegerDays remaining in billing period
proratedMonthsLeftintegerMonths remaining in billing period

400 Bad Request — Validation error if powerUsers is missing or below minimum.


Purchase Power Users

Purchases additional power users for the MSP's pool. Billed immediately on a prorated basis.

POST /pubapi/v1/msp/plans/{planId}/power-users/purchase/

Path Parameters

ParameterTypeRequiredDescription
planIdstringYesPlan identifier

Request Body

FieldTypeRequiredConstraintsDescription
powerUsersintegerYesmin: 1Target number of power users (absolute count, not delta)

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/msp/plans/{planId}/power-users/purchase/" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "powerUsers": 50
}'

200 OK — Same response fields as Get Power Users Quote.

400 Bad Request — Validation error if powerUsers is missing or below minimum.


Allocate Power Users to Domain

Allocates power users from the MSP's pool to a specific customer domain.

POST /pubapi/v1/msp/domains/{domain}/power-users/allocate

Path Parameters

ParameterTypeRequiredDescription
domainstringYesThe customer domain name

Request Body

FieldTypeRequiredConstraintsDescription
powerUsersintegerYesmin: 1Target number of power users to allocate to the domain (absolute count, not delta)

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/msp/domains/{domain}/power-users/allocate" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "powerUsers": 10
}'

200 OK

FieldTypeDescription
domainstringThe customer domain name
previousPowerUsersintegerPower user count before allocation
newPowerUsersintegerPower user count after allocation
poolAvailableAfterintegerMSP pool power users remaining after allocation

400 Bad Request

Error CodeDescription
invalid_power_users_valuepowerUsers is missing, not an integer, zero, or negative
customer_is_trialPower user allocation is not allowed for trial customers
power_user_allocation_errorpowerUsers is below domain's current consumption, below current allocated count (decrease not allowed), exceeds reseller's available pool (non-DLC), or exceeds plan maximum (DLC)

404 Not Found — domain_not_found — domain does not exist or belongs to a different reseller.


Trial Management

MSP resellers can create trial domains and convert them to paid subscriptions via the MSP Public API.

Start New Trial

Creates a new trial domain under the MSP reseller account.

Request

POST /pubapi/v1/msp/trials/

Request Body

FieldTypeRequiredConstraintsDescription
domainstringYesmaxLength: 50The domain name for the trial
idintegerYes—Plan ID (from GET /msp/plans)
powerUsersintegerYesmin: 1Number of power user licenses
storageGBintegerYesmin: 1Storage allocation in GB
regionstringYesmaxLength: 50Region for domain provisioning. See Regions below
usernamestringNomaxLength: 255Admin username
passwordstringNomaxLength: 255Admin password (write-only)
firstNamestringNomaxLength: 255Admin first name
lastNamestringNomaxLength: 255Admin last name
emailstringNoformat: emailAdmin email address
phonestringNomaxLength: 50, default: ""Admin phone number

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/msp/trials/" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "domain": "acmetrial",
  "id": 42,
  "powerUsers": 25,
  "storageGB": 500,
  "region": "sjc"
}'

Regions

ValueDescription
sjcNorth America — US West
avlNorth America — US East
am2Europe — Belgium
me1Middle East — UAE

Response

201 Created

FieldTypeDescription
domainstringThe trial domain name
domainUrlstringFull URL of the provisioned domain
trialStartstring (date)Trial start date (ISO 8601)
trialEndstring (date)Trial end date (ISO 8601)
powerUsersintegerNumber of power user licenses
storageGBintegerStorage allocation in GB

Example Response

{
  "domain": "acmetrial",
  "domainUrl": "https://acmetrial.egnyte.com",
  "trialStart": "2026-06-01",
  "trialEnd": "2026-06-30",
  "powerUsers": 25,
  "storageGB": 500
}

400 Bad Request

CodeDescriptionResolution
Validation errorMissing required fields or invalid valuesCheck fieldName and nonFieldErrors in the response body

409 Conflict

CodeDescriptionResolution
domain_takenDomain name already takenUse a different domain name; check suggestions in the response for alternatives

422 Unprocessable Entity

CodeDescriptionResolution
trials_lockedTrials locked for this plan typeContact your MSP account manager to unlock trials for this plan

Activate Trial

Converts a trial domain to a paid subscription.

Request

POST /pubapi/v1/msp/trials/{domain}/activate/

Path Parameters

ParameterTypeRequiredDescription
domainstringYesThe trial domain name to activate

Request Body

FieldTypeRequiredConstraintsDescription
planIdintegerYesmin: 1Target plan ID (from GET /msp/plans)
powerUsersintegerYesmin: 1Number of power user licenses. Must be ≥ actual current usage.
storageGBintegerYesmin: 1Storage in GB. Must be ≥ actual current usage.

Example Request

curl -i -X POST "https://{domain}.egnyte.com/pubapi/v1/msp/trials/{domain}/activate/" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     -d '{
  "planId": 42,
  "powerUsers": 25,
  "storageGB": 1000
}'

Response

200 OK

FieldTypeDescription
domainstringThe activated domain name
domainUrlstringFull URL of the domain
activationDatestring (date)Date the domain was converted to paid (ISO 8601)

Example Response

{
  "domain": "acmetrial",
  "domainUrl": "https://acmetrial.egnyte.com",
  "activationDate": "2026-06-15"
}

400 Bad Request

CodeDescriptionResolution
domain_not_trialDomain exists but is already a paid subscriptionVerify the domain is currently in trial status
insufficient_pool_resourcesRequested power users exceed available pool capacityReduce powerUsers or increase pool capacity
Validation errorpowerUsers or storageGB below actual current usageIncrease values to meet or exceed current usage

404 Not Found

CodeDescriptionResolution
domain_not_foundNo domain with that name exists under this MSP resellerVerify the domain name and ensure it was created under your MSP account

502 Bad Gateway

CodeDescriptionResolution
trial_activation_failedCFS activation call returned non-200Retry the request or contact support if the issue persists

Users

Endpoints to list and inspect MSP Reseller users for the requesting reseller.

List Users

Returns a paginated list of users belonging to the requesting MSP reseller.

GET /pubapi/v1/msp/users

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/users" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "userId": "9782be00-5b7d-46c7-abc3-9d2102564081",
      "fullName": "user1",
      "email": "user1@egnyte.com",
      "defaultAccess": "Administrator",
      "isActive": true,
      "isTfaEnabled": false,
      "isSsoEnabled": true,
      "lastLoginAt": "2025-07-10T11:30:06",
      "dateJoined": "2024-06-30T04:00:00"
    },
    {
      "userId": "9efdfaa0-c33e-4712-992e-3a2a1399ebab",
      "fullName": "user2",
      "email": "user2@egnyte.com",
      "defaultAccess": "IT Admin",
      "isActive": true,
      "isTfaEnabled": false,
      "isSsoEnabled": true,
      "lastLoginAt": "2025-05-26T10:36:16",
      "dateJoined": "2024-11-30T12:30:01"
    }
  ]
}
FieldTypeDescription
countintegerTotal number of users
nextstring | nullURL to the next page of results
previousstring | nullURL to the previous page of results
resultsarrayList of user objects

Each user object:

FieldTypeDescription
userIdstring (UUID)Unique identifier of the user
fullNamestringUser's full name
emailstringUser's email address
defaultAccessstringDefault access role. One of: Administrator, IT Admin, IT Technician, User, BillingAdmin
isActivebooleanWhether the user account is active
isTfaEnabledbooleanWhether two-factor authentication is enabled
isSsoEnabledbooleanWhether SSO is enabled for the user
lastLoginAtstring (datetime) | nullTimestamp of the user's last login
dateJoinedstring (datetime)Timestamp when the user account was created

Get User Details

Returns a single user belonging to the requesting MSP reseller.

GET /pubapi/v1/msp/users/{userId}

Path Parameters

ParameterTypeRequiredDescription
userIdstring (UUID)YesUser identifier

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/users/{userId}" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "fullName": "Jane Doe",
  "email": "jane.doe@example.com",
  "defaultAccess": "Administrator",
  "isActive": true,
  "isTfaEnabled": true,
  "isSsoEnabled": false,
  "lastLoginAt": "2024-05-08T10:15:30Z",
  "dateJoined": "2024-03-19T00:00:00Z",
  "accessTypeByDomain": {
    "testdomain1": "Administrator",
    "testdomain2": "No Access"
  }
}

Same base fields as each object in List Users except userId is omitted, plus:

FieldTypeDescription
accessTypeByDomainobjectMap of domain name → role for each domain the user has access to. Domain-level roles: IT Admin, IT Technician, No Access

404 Not Found

{ "message": "No user found for the given userId", "code": "user_not_found" }

List User Activity Logs

Returns a paginated list of activity logs for the given MSP user, newest first.

GET /pubapi/v1/msp/users/{userId}/logs

Path Parameters

ParameterTypeRequiredDescription
userIdstring (UUID)YesUser identifier

Query Parameters

ParameterTypeRequiredDescription
fromstring (date)NoReturn logs on or after this date (ISO 8601, must not be in the future)
tostring (date)NoReturn logs on or before this date (ISO 8601, must not be in the future and must be ≥ from)

Example Request

curl -i -X GET "https://{domain}.egnyte.com/pubapi/v1/msp/users/{userId}/logs?from=2026-07-01&to=2026-07-31" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

200 OK

{
  "count": 4,
  "next": null,
  "previous": null,
  "results": [
    {
      "kind": "UserChange",
      "details": "Last Name: testtwo -> testthree",
      "target": "User: testuser12@egnyte.com",
      "timestamp": "2026-07-16T02:49:44.962742",
      "author": "testuser@egnyte.com"
    },
    {
      "kind": "PasswordReset",
      "details": "",
      "target": "User: testuser45@egnyte.com",
      "timestamp": "2026-07-16T02:49:12.540354",
      "author": "testuser@egnyte.com"
    },
    {
      "kind": "UserStatusChange",
      "details": "Unblocked testuser34@egnyte.com successfully.",
      "target": "User: testuser45@egnyte.com",
      "timestamp": "2026-07-16T02:48:41.085499",
      "author": "testuser@egnyte.com"
    },
    {
      "kind": "UserAdded",
      "details": "",
      "target": "User: testuser2@egnyte.com",
      "timestamp": "2026-07-16T02:47:30.989140",
      "author": "testuser@egnyte.com"
    }
  ]
}
FieldTypeDescription
countintegerTotal number of log entries
nextstring | nullURL to the next page of results
previousstring | nullURL to the previous page of results
resultsarrayList of log entry objects

Each log entry:

FieldTypeDescription
kindstringAction performed. See Log entry kinds below
detailsstringSummary of what changed — field diffs, affected domain, or a status message. Empty string when the action carries no extra detail
targetstringObject affected by the event, if applicable
timestampstring (datetime)When the event occurred
authorstringEmail of the user who performed the action

Log entry kinds

KindDescription
UserChangeUser profile or access changes (e.g. first name, last name, email, access role)
UserStatusChangeUser block or unblock status changes
LoginToDomainUser login to a specific domain
ObjChangedOne or more fields on an object were modified; details list each field with old and new values
UserAddedUser added under the MSP reseller
PasswordResetUser password reset action
CustomerChangeCustomer-level config update (like invoice emails, status)
CustomerCCUpdateCustomer credit card or billing information updated
CustomerSubscribedCustomer subscribed to a plan

400 Bad Request

CodeDescription
request_schema_errorfrom or to is in the future, or from is after to

404 Not Found

{ "message": "No user found for the given userId", "code": "user_not_found" }