MSP

MSP (Managed Service Provider) contains multiple Organizations.

MSP

Create MSP

POST /api/v1/msps

Request

{
    "name": "MSP"
}

Update an MSP

PUT /api/v1/msps/:msp_id

Request

{
    "name": "MSP"
}

For advanced tier (uMSPs), custom url is also available

{
    "name": "MSP",
    "url": "https://.." 
}

Get MSP Detail

GET /api/v1/msps/:msp_id

Response

{
    "id": "9520c63a-f7b3-670c-0944-727774d5a722",
    "name": "MSP",
    "tier": "base"
}
{
    "id": "9520c63a-f7b3-670c-0944-727774d5a722",
    "name": "MSP",
    "tier": "advanced",
    "url": "https://..",
    "logo_url": "https://...."
}

Upload Logo (only for advanced MSP tier)

POST /api/v1/msps/:msp_id/logo
DELETE /api/v1/msps/:msp_id/logo

Delete MSP

Deleting MSP removes the MSP and OrgGroup under the MSP as well as all privileges associated with them. It does not remove any Org or Admins

DELETE /api/v1/msps/:msp_id

Create an Org under MSP

POST /api/v1/msps/:msp_id/orgs

Request

{
    "name": "Motel 6",
    "orggroup_ids": [ "507f1bab-13ba-73e2-f291-2bcb8d1362b0" ]
}

Assign Org to MSP

PUT /api/v1/msps/:msp_id/orgs

Request

{
    "op": "assign"
    "org_ids": [
        "2818e386-8dec-2562-9ede-5b8a0fbbdc71"
    ]
}

Parameters

Name Type Description
op string operation (assign/unassign)
org_ids list list of org_id

Response

Status: 200 OK

Remove Org from MSP

PUT /api/v1/msps/:msp_id/orgs

Request

{
    "op": "unassign"
    "org_ids": [
        "2818e386-8dec-2562-9ede-5b8a0fbbdc71"
    ]
}

Parameters

Name Type Description
op string operation (assign/unassign)
org_ids list list of org_id

Response

Status: 200 OK

Get Orgs in MSP

GET /api/v1/msps/:msp_id/orgs

Org Group

Org Group Schema

{
    "name": "West"
}

Get Org Groups in a MSP

GET /api/v1/msps/:msp_id/orggroups

Create Org Group

POST /api/v1/msps/:msp_id/orggroups

Get an Org Group in MSP

GET /api/v1/msps/:msp_id/orggroups/:orggroup_id

Update an Org Group in MSP

PUT /api/v1/msps/:msp_id/orggroups/:orggroup_id

Delete an Org Group

DELETE /api/v1/msps/:msp_id/orggroups/:orggroup_id

Search Org in MSP

GET /api/v1/msps/:msp_id/orgs/search?sub_insufficient=true

Supported Filters

Name Type Description
name string org name
org_id string org id
trial_enabled boolean if this org is under trial period
usage_types list a list of types that enabled by usage
sub_insufficient boolean if this org has sufficient subscription

Response

{
    "results": [
        {
            "sub_ana_required": 9,
            "sub_ast_required": 3,
            "sub_ex12_required": 1,
            "sub_eng_required": 3,
            "sub_man_required": 9,
            "sub_ast_entitled": 5,
            "sub_vna_entitled": 1,
            "num_unassigned_aps": 1,
            "num_sites": 5,
            "num_aps": 9,
            "timestamp": 1614322563.513937,
            "num_switches": 1,
            "org_id": "bb1a8bf6-4064-4bbd-83dc-8053a663cf65",
            "name": "Test Org",
            "msp_id": "d287e62f-9689-4c05-85d8-f2b9ba0a531f",
            "sub_insufficient": true,
            "trial_enabled" : false,
            "usage_types" : [
                "sub_eng"
            ]
        },
        {
            "sub_ana_required": 1,
            "sub_man_required": 1,
            "sub_ana_entitled": 1,
            "sub_man_entitled": 1,
            "num_sites": 1,
            "num_aps": 1,
            "timestamp": 1614309876.500955,
            "org_id": "0fb81690-7b74-4a56-b984-9596d1d1534f",
            "name": "Rogue Test1",
            "msp_id": "d287e62f-9689-4c05-85d8-f2b9ba0a531f",
            "sub_insufficient": false
        }
    ],
    "start": 1613778578.4365668,
    "end": 1614383378.4365287,
    "limit": 10,
    "total": 2
}

Search for Org in MSP

GET /api/v1/msps/:msp_id/search?type=orgs&q=stan&limit=10&page=2

Request

Name Type Description
type string orgs
q string search string

Response

{
    "page": 1,
    "limit": 10,
    "total": 60,

    "results": [
        {
            "type": "orgs",
            "text": "Stanford",
            "id": "37cff3c6-a361-deea-2c79-114ebb76c1f8"
        },
        ...
    ]
}

License

Get License

GET /api/v1/msps/:msp_id/licenses

Response

{
    "licenses": [
        {
            "order_id": "00000464",
            "subscription_id": "SUB-0000144",
            "type": "SUB-MAN",
            "start_time": 1504828800,
            "end_time": 1520380800,
            "quantity": 180
        },
        {
            "order_id": "00000464",
            "subscription_id": "SUB-0000145",
            "type": "SUB-MAN",
            "start_time": 1504828800,
            "end_time": 1520380800,
            "quantity": 30
        }
        {
            "order_id": "00000464",
            "subscription_id": "SUB-0000146",
            "type": "SUB-LOC",
            "start_time": 1504828800,
            "end_time": 1520380800,
            "quantity": 120
        }
    ],
    "amendments": [
        {
            "id": "2b9116ab-cd1e-e897-6e08-31fccd88e792",
            "subscription_id": "SUB-0000144",
            "type": "SUB-MAN",
            "start_time": 1504828800,
            "end_time": 1520380800,
            "quantity": -30
        },
        {
            "id": "4e974f27-fcbc-03cb-caa4-688e20aa539f",
            "subscription_id": "SUB-0000146",
            "type": "SUB-LOC",
            "start_time": 1504828800,
            "end_time": 1520380800,
            "quantity": 75
        },
    ],
    "entitled": {
        "SUB-MAN": 180,
        "SUB-LOC": 195
    }
}

Definitions

Name Type Description
licenses list list of licenses
type string subscription type, SUB-MAN / SUB-LOC / SUB-AST / SUB-VNA / SUB-DATA
start_time long start date of the license term
end_time long end date of the license term
quantity int number of devices entitled for this license
entitled object currently entitled for each license type

Claim an Order by Activation Code

POST /api/v1/msps/:msp_id/claim

Example

{
    "code": "ZHT3K-H36DT-MG85D-M61AC"
}

Parameters

Name Type Description
code string activation code

Response of the license(s) that are successfully claimed and applied

{
    "license_added": [
        {
            "type": "SUB-MAN",
            "start": 1504828800,
            "end": 1520380800,
            "quantity": 180
        },
        {
            "type": "SUB-LOC",
            "start": 1504828800,
            "end": 1520380800,
            "quantity": 120
        }
    ],
    "license_duplicated": [
        {
            "type": "SUB-MAN",
            "start": 1504828800,
            "end": 1520380800,
            "quantity": 180
        }
    ],
    "license_error": [
        {
            "order": "00000464",
            "reason": ""
        }
    ]
}

Response when the key is invalid (or already used)

Status: 400 Bad Request

Move License from MSP to another Org under the MSP

PUT /api/v1/msps/:msp_id/licenses

Request

{
    "op": "amend",
    "subscription_id": "SUB-0000144",
    "dst_org_id": "3eff35f7-c218-894e-bca2-24e5325601cc",
    "quantity": 10
}

Parameters

Name Type Description
op string operation (amend/unamend/delete/annotate)
subscription_id string license id
dst_org_id string destination org id
quantity int quantity

Undo the License Move

PUT /api/v1/msps/:msp_id/licenses

Request

{
    "op": "unamend",
    "amendment_id": "2b9116ab-cd1e-e897-6e08-31fccd88e792",
}

Delete License

PUT /api/v1/msps/:msp_id/licenses

Request

{
    "op": "delete",
    "subscription_id": "SUB-0000144"
}

Annotate a License

PUT /api/v1/msps/:msp_id/licenses

Request

{
    "op": "annotate",
    "subscription_id": "SUB-000144",
    "notes": "customer notes"
}

Audit Logs

Audit logs records all administrative activities in a MSP

Get a list of change logs for the current MSP

GET /api/v1/msps/:msp_id/logs?start=1431298000&end=1431384000&limit=100

Supported Filters

Name Type Description
org_id string org id
admin_name string admin name or email
message string message

Response

The logs are always sorted by time in descending order

{
    "start": 1431298000,
    "end":   1431384000,
    "limit": 100,

    "total": 135,
    "results": [
        {
            "timestamp": 1431382121,
            "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71",
            "msp_id": "d287e62f-9689-4c05-85d8-f2b9ba0a531f",
            "admin_id": "72bfa2bd-e58a-4670-9d20-a1468f7a6f58",
            "admin_name": "test@mistsys.com",
            "message": "TEST AUDIT",
            "id": "c6f9347b-b0a4-4a23-b927-fa9249f2ffb2"
        }
    ]
}
Name Type Description
timestamp long start time, in epoch
org_id string org id
msp_id string msp id
admin_id string admin id
admin_name string name of the admin that performs the action
message string log message
before object field values prior to the change
after object field values after the change

Count by Distinct Attributes of Audit Logs

GET /api/v1/msps/:msp_id/logs/count?distinct=admin_name

Request

Name Type Description
distinct string admin_id / admin_name / message / org_id, default is admin_name

Response

{
    "start": 1511967600,
    "end": 1513177200,
    "limit": 10,
    "distinct": "admin_name",

    "total": 2,
    "results": [
        {
            "admin_name": "John Smith john.smith@corp.com",
            "count": 61
        },
        {
            "admin_name": "Eric Sky eric@corp.com",
            "count": 44
        }
    ]
}

MSP Insights

Get Insight Metrics

See GET AVAILABLE_INSIGHT METRICS for metrics description of MSP Scope

GET /api/v1/msps/:msp_id/insights/:metric

Response

{
    "start": 1428939600,
    "end":   1428954000,
    "interval": 3600,

    // data
    "results": [
        {
            // results depends on :metric
        },
        ...
    ],
}

MSP Admins

Get MSP Admins

Get a list of people who can manage the MSP/Org(s) under the MSP

GET /api/v1/msps/:msp_id/admins

Response

[
    {
        "admin_id": "456b7016-a916-a4b1-78dd-72b947c152b7",
        "first_name": "Joe",
        "last_name": "Smith",
        "two_factor_verified": true,
        "privileges": [
            { "scope":"msp", "role": "admin" },
            { "scope":"org", "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71", "role": "admin" },
            { "scope":"orggroup", "orggroup_id": "507f1bab-13ba-73e2-f291-2bcb8d1362b0", "role": "read" }
        ]
    }
]

Response Definition

Name Type Description
admin_id string admin id
first_name string first name
last_name string last name
two_factor_verified boolean two factor status
privileges list list of privileges the admin has on the MSP / Orgs / OrgGroups
scope string msp / org / orggroup
role string admin / write / read / helpdesk

Update MSP Admins

Update admin privileges under the Org

PUT /api/v1/msps/:msp_id/admins/:admin_id

Request

{
    "privileges": [
        { "scope":"msp", "role": "admin" },
        { "scope":"org", "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71", "role": "admin" },
        { "scope":"orggroup", "orggroup_id": "507f1bab-13ba-73e2-f291-2bcb8d1362b0", "role": "read" }
    ]
}

Revoke Admin

This removes all privileges this admin has against the MSP. This goes deep all the way to the sites

DELETE /api/v1/msps/:msp_id/admins/:admin_id

Invite MSP Admin

A MSP admin can invite other admin to manage (admin or read) the MSP and/or Org(s) under the MSP.

POST /api/v1/msps/:msp_id/invites

Request

{
    "email": "joe@abc.com",
    "name": "Richard",
    "hours": 24,
    "privileges": {
        { "scope":"msp", "role": "admin" },
        { "scope":"org", "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71", "role": "admin" },
        { "scope":"orggroup", "orggroup_id": "507f1bab-13ba-73e2-f291-2bcb8d1362b0", "role": "read" }
    }
}

Parameters

Name Type Description
email string email - admin_id is not exposed
name string name, used in the invitation text
privileges list list of privileges the admin has on the MSP / Orgs / OrgGroups
scope string msp / org / orggroup
role string admin / write / read
hours int optional, how long the invite should be valid, default is 1 day, maximum is 1 week.

Response

Status: 200 OK

An email will also be sent to the user with a link to https://manage.mist.com/verify/invite?token=:token

Verify Invitation

POST /api/v1/invite/verify/:token

Response if successful

Status: 200 OK

NOTE: another call to GET /api/v1/self is required to see the new set of privileges

Un-invite Admin

DELETE /api/v1/msps/:msp_id/invites/:invite_id

Update the Invite

PUT /api/v1/msps/:msp_id/invites/:invite_id

Request

{
    "hours": 24,
    "privileges": {
        { "scope":"org", "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71", "role": "read" }
    }
}

Parameters

Name Type Description
hours int optional, how long the invite should be valid, default is 1 day, maximum is 1 week.
privileges list list of privileges the admin has on the MSP / Orgs / OrgGroups
scope string msp / org / orggroup

SSO / SAML

Create SSO

POST /api/v1/msps/:msp_id/ssos

Request

{
    "name": "onelogin",
    "issuer": "https://app.onelogin.com/saml/metadata/138130"
    "idp_cert": "-----BEGIN CERTIFICATE-----\nMIIFZjCCA06gAwIBAgIIP61/1qm/uDowDQYJKoZIhvcNAQELBQE\n-----END CERTIFICATE-----",
    "idp_sign_algo": "sha256",
    "idp_sso_url": "https://yourorg.onelogin.com/trust/saml2/http-post/sso/138130",
    "nameid_format": "email",

    "ignore_unmatched_roles": false,
    "default_role": null,

    // some IdP support a custom logout URL that is different from SP-initiated SLO process
    "custom_logout_url": "https://6.4.5.7/saml/idp/SingleLogoutService.php?param1=value1"
}

Definition

Name Type Description
name string name
issuer string IDP issuer URL
idp_cert string IDP Cert (used to verify the signed response)
idp_sso_url string IDP Single-Sign-On URL
nameid_format string email (default) / unspecified
ignore_unmatched_roles boolean ignore any unmatched roles provided in assertion. By default, an assertion is treated as invalid for any unmatched role
default_role string default role to assign if there’s no match. By default, an assertion is treated as invalid when there’s no role matched
role_attr_from string optional, name of the attribute in SAML Assertion to extract role from (defaults to Role)
role_attr_extraction string optional, user defined role parsing scheme. See Supported Role Parsing Schemes
custom_logout_url string optional, a URL we will redirect the user after user logout from Mist (for some IdP which supports a custom logout URL that is different from SP-initiated SLO process)

Supported Role Parsing Schemes

Name Scheme
cn - The expected role attribute format in SAML Assertion is “CN=cn,OU=ou1,OU=ou2,…”

- CN (the key) is case insensitive and exactly 1 CN is expected (or the entire entry will be ignored)

E.g. if role attribute is “CN=cn,OU=ou1,OU=ou2” then parsed role value is “cn”

Get All SSO Configured for the MSP

GET /api/v1/msps/:msp_id/ssos

Response

[
    {
        "name": "onelogin",
        "issuer": "https://app.onelogin.com/saml/metadata/138130"
        "idp_cert": "-----BEGIN CERTIFICATE-----\nMIIFZjCCA06gAwIBAgIIP61/1qm/uDowDQYJKoZIhvcNAQELBQE\n-----END CERTIFICATE-----",
        "idp_sign_algo": "sha256",
        "idp_sso_url": "https://yourorg.onelogin.com/trust/saml2/http-post/sso/138130"
    }
]

Update SSO

PUT /api/v1/msps/:msp_id/ssos/:sso_id

Delete SSO

DELETE /api/v1/msps/:msp_id/ssos/:sso_id

Get SAML Metadata

GET /api/v1/msps/:msp_id/ssos/:sso_id/metadata

Response

{
    "entity_id": "https://api.mist.com/api/v1/saml/llDfa13f/login",
    "acs_url": "https://api.mist.com/api/v1/saml/llDfa13f/login",
    "logout_url": "https://api.mist.com/api/v1/saml/llDfa13f/logout",
    "metadata_xml": "<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://api.mist.com/api/v1/saml/llDfa13f/login" validUntil="2027-10-12T21:59:01Z" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://api.mist.com/api/v1/saml/llDfa13f/login" index="0" isDefault="true"/></md:SPSSODescriptor></md:EntityDescriptor>"
}

Download SAML Metadata

GET /api/v1/msps/:msp_id/ssos/:sso_id/metadata.xml

Response

<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://api.mist.com/api/v1/saml/5hdF5g/login" validUntil="2027-10-12T21:59:01Z" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://api.mist.com/api/v1/saml/5hdF5g/logout" />
        <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
        <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://api.mist.com/api/v1/saml/5hdF5g/login" index="0" isDefault="true"/>
        <md:AttributeConsumingService index="0">
            <md:ServiceName xml:lang="en-US">Mist</md:ServiceName>
            <md:RequestedAttribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="true"/>
            <md:RequestedAttribute Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
            <md:RequestedAttribute Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" isRequired="false"/>
        </md:AttributeConsumingService>
    </md:SPSSODescriptor>
</md:EntityDescriptor>

Get Latest SSO Failures

GET /api/v1/msps/:msp_id/ssos/:sso_id/failures

Response

{
    "results": [
        {
            "timestamp": 1431382121,
            "detail": "Role attribute missing",
            "saml_assertion_xml": "<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:nam..."            
        }
    ]
}

Create SSO Role

POST /api/v1/msps/:msp_id/ssoroles

Request

{
    "name": "NOC",
    "privileges": [
        { "scope":"msp", "role": "admin" },
        { "scope":"org", "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71", "role": "admin" },
        { "scope":"orggroup", "orggroup_id": "507f1bab-13ba-73e2-f291-2bcb8d1362b0", "role": "read" }
    ]
}

Definition

Name Type Description
name string name that would match the Role from SSO Login. unique per Org, maximum length is 32
privileges list list of privileges the admin has on the MSP / Orgs / OrgGroups
scope string msp / org / orggroup

Update SSO Role

PUT /api/v1/msps/:msp_id/ssoroles/:ssorole_id

Request

{
    "name": "NOC",
    "privileges": [
        { "scope":"msp", "role": "admin" },
        { "scope":"org", "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71", "role": "admin" },
        { "scope":"orggroup", "orggroup_id": "507f1bab-13ba-73e2-f291-2bcb8d1362b0", "role": "read" }
    ]
}

Get All SSO Roles

GET /api/v1/msps/:msp_id/ssoroles

Delete SSO Role

DELETE /api/v1/msps/:msp_id/ssoroles/:ssorole_id

Get Inventory by MAC

GET /api/v1/msps/:msp_id/inventory/:mac

Response

{
    "serial": "FXLH2015150025",
    "model": "AP200",
    "type": "ap",
    "mac": "5c5b35000018",
    "org_id": "2818e386-8dec-2562-9ede-5b8a0fbbdc71",
    "site_id": "4ac1dcf4-9d8b-7211-65c4-057819f0862b"
}

Tickets

Get Tickets of a MSP

GET /api/v1/msps/:msp_id/tickets?start=1546300800&end=-1d

Parameters

Name Type Description
start string start datetime, can be epoch or relative time like -1d, -1w; -1d if not specified
end string end datetime, can be epoch or relative time like -1d, -2h
duration string duration like 7d, 2w

NOTE: end & duration if both specified, will take precedence over start time

Response

[
    {
        "id": "00000000-0000-0000-0000-00000000000c",
        "org_id": "9291176a-0000-000-0000-002e208b2d3f",
        "created_at": 1453908369,
        "updated_at": 1453908369,
        "subject": "Please add me",
        "status": "open",
        "type": "question",
        "requester": "John Smith"
    }
]

Definitions

Name Type Description
id string id of the ticket
org_id string id of the Org
created_at int when the ticket was created
updated_at int when the ticket was last updated
type string question (default) / bug / critical
subject string subject
status string open / pending / solved / closed
requester string name of the requester

Ticket Status

Count tickets

GET /api/v1/msps/:msp_id/tickets/count?distinct=status

Definitions

Name Type Description
distinct string status (default) / type / org_id

Response

{
    "limit": 1000,
    "distinct": "status",
    "total": 5,
    "results": [
        {
            "status": "closed",
            "count": 24
        },
        {
            "status": "open",
            "count": 12
        },
        {
            "status": "solved",
            "count": 15
        },
        {
            "status": "pending",
            "count": 10
        },
        {
            "status": "hold",
            "count": 3
        }
    ]
}

Marvis Action

Count Marvis actions

GET /api/v1/msps/:msp_id/suggestion/count?distinct=org_id

Definitions

Name Type Description
distinct string org_id (default)

Response

{
    "limit": 1000,
    "distinct": "status",
    "total": 3,
    "results": [
        {
            "status": "002e176a-0000-000-1111-002e208b20e1",
            "count": 24
        },
        {
            "status": "2d3f176a-0000-000-2222-002e208f176a",
            "count": 12
        },
        {
            "status": "08b2176a-0000-000-3333-002e208b2d3f",
            "count": 15
        },
    ]
}