From ninjaone-rmm
Provides NinjaOne API authentication (OAuth 2.0), cursor-based pagination, and rate limiting/error handling patterns. Essential for all NinjaOne API operations.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ninjaone-rmm:api-patternsWhen to use
When working with NinjaOne API authentication, pagination, rate limiting, and error handling patterns. Use when: ninjaone api, ninjarmm api, ninja authentication, ninja oauth, ninja rate limit, or ninja pagination.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
The NinjaOne Public API uses OAuth 2.0 for authentication and provides RESTful endpoints for all platform operations.
The NinjaOne Public API uses OAuth 2.0 for authentication and provides RESTful endpoints for all platform operations.
| Region | Base URL |
|---|---|
| United States | https://app.ninjarmm.com |
| European Union | https://eu.ninjarmm.com |
| Oceania | https://oc.ninjarmm.com |
Use the base URL matching your NinjaOne instance region.
NinjaOne uses OAuth 2.0 with the following scopes:
monitoring - Read monitoring datamanagement - Manage devices and organizationscontrol - Remote control capabilitiesPOST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&scope=monitoring management control
Response:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "monitoring management control"
}
Include in all API requests:
GET /api/v2/organizations
Authorization: Bearer eyJ...
Tokens expire after the expires_in period. Request a new token before expiration.
GET /api/v2/organizations
Authorization: Bearer {token}
Accept: application/json
POST /api/v2/organizations
Authorization: Bearer {token}
Content-Type: application/json
Accept: application/json
{
"name": "New Organization",
"description": "Description here"
}
PATCH /api/v2/device/{id}
Authorization: Bearer {token}
Content-Type: application/json
{
"displayName": "Updated Name"
}
NinjaOne uses cursor-based pagination:
GET /api/v2/organizations?pageSize=50
{
"results": [...],
"pageInfo": {
"hasNextPage": true,
"endCursor": "abc123xyz"
}
}
GET /api/v2/organizations?pageSize=50&after=abc123xyz
let cursor = null;
let allResults = [];
do {
const url = cursor
? `/api/v2/organizations?pageSize=100&after=${cursor}`
: '/api/v2/organizations?pageSize=100';
const response = await fetch(url, { headers });
const data = await response.json();
allResults = allResults.concat(data.results);
cursor = data.pageInfo.hasNextPage ? data.pageInfo.endCursor : null;
} while (cursor);
NinjaOne implements rate limiting to ensure API stability:
Watch for these response headers:
X-RateLimit-Limit - Max requests per windowX-RateLimit-Remaining - Requests remainingX-RateLimit-Reset - Window reset timeWhen rate limited:
{
"error": "rate_limit_exceeded",
"message": "Too many requests",
"retry_after": 60
}
| Code | Meaning | Action |
|---|---|---|
| 200 | Success | Process response |
| 201 | Created | Resource created successfully |
| 204 | No Content | Success, no body |
| 400 | Bad Request | Check request format |
| 401 | Unauthorized | Refresh token |
| 403 | Forbidden | Check permissions |
| 404 | Not Found | Verify resource exists |
| 409 | Conflict | Resource conflict |
| 422 | Validation Error | Check field values |
| 429 | Rate Limited | Wait and retry |
| 500 | Server Error | Retry with backoff |
{
"error": "validation_error",
"message": "Invalid field value",
"details": {
"field": "name",
"issue": "Required field missing"
}
}
async function makeRequest(url, options) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
await sleep(retryAfter * 1000);
return makeRequest(url, options);
}
if (response.status === 401) {
await refreshToken();
return makeRequest(url, options);
}
if (!response.ok) {
const error = await response.json();
throw new ApiError(error.message, response.status);
}
return response.json();
}
PUT /api/v2/webhook
Content-Type: application/json
{
"url": "https://your-server.com/webhook",
"events": ["ALERT_TRIGGERED", "DEVICE_OFFLINE"]
}
DELETE /api/v2/webhook
| Event | Description |
|---|---|
ALERT_TRIGGERED | New alert created |
ALERT_CLEARED | Alert resolved |
DEVICE_ONLINE | Device connected |
DEVICE_OFFLINE | Device disconnected |
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin ninjaone-rmmAuthenticates, paginates, filters (OData), and handles errors for the ConnectWise Automate REST API. Covers token management and best practices for integrations.
Manages NinjaOne organizations: create, list, manage locations, and configure policies for MSP clients.
Covers authentication, pagination, rate limiting, and error handling for the Atera REST API using X-API-KEY, OData-style pagination, and 700 req/min rate limits.