Initial skills documentation — 25 categories, all SKILL.md + references + scripts

This commit is contained in:
root
2026-07-15 17:42:20 -04:00
commit 1b4fcd4427
976 changed files with 188344 additions and 0 deletions
@@ -0,0 +1,105 @@
# JS-Rendered API Documentation Pages
Pattern observed when browsing OpenAPI/Redoc-styled docs (like RingLogix, Swagger, Stoplight):
## What the Accessibility Tree Shows
- **Sidebar/nav tree** — fully accessible via `browser_snapshot(full=true)`. Category names, endpoint paths, and hierarchical structure appear as text nodes.
- **Main content pane** — the actual API spec (endpoint details, parameters, schemas, sample requests) renders in a JavaScript-driven viewer (Redoc, Swagger UI, Scalar). The accessibility tree may show these as opaque elements with `role="region"` or similar, with no rich text content.
- **Search/filter box** at the top — accessible for navigation.
## Recommended Probe Sequence
1. `browser_navigate(url)` — loads the page
2. `browser_snapshot(full=true)` — get the full sidebar nav structure
3. If sidebar content is present but main pane is empty:
- `browser_click(element)` on a sidebar link to navigate to a specific endpoint
- `browser_snapshot(full=true)` again after navigation (JS may then render that section)
- Or use `browser_vision` to screenshot and analyze visually
## CDP Bulk Extraction (for large Redoc/Swagger pages)
When the SPA loads a huge page (e.g. 238 endpoints, 186K chars of docs), `browser_snapshot` truncates at ~18K lines and `browser_console` JS selectors may find no `<nav>` element (Redoc renders into custom elements or shadow DOM). Use this CDP-based probe sequence instead:
### Step 1: Navigate and identify the correct target
```
browser_navigate(url)
// Wait ~2s for SPA bootstrap
browser_snapshot(full=true) // Sidebar should be visible
```
### Step 2: List all browser targets via CDP
```
browser_cdp(method="Target.getTargets", params={})
```
Look for the page with the expected title (NOT `chrome://newtab`). Returns `targetInfos` array — the target you navigated to has the real URL and `title` field.
### Step 3: Extract text via CDP on the correct target
```
browser_cdp(
target_id="<target ID from Step 2>",
method="Runtime.evaluate",
params={
expression: "document.body.innerText.substring(0, 8000)",
returnByValue: true
}
)
```
Page through sections by changing the substring range. For large docs (e.g. RingLogix: 186K chars), use intervals of 3000-4000 at a time.
### Step 4: Get full sidebar nav list via CDP
```
browser_cdp(
target_id="<target ID>",
method="Runtime.evaluate",
params={
expression: "Array.from(document.querySelectorAll('li a')).map(a => a.textContent.trim()).filter(t => t)",
returnByValue: true
}
)
```
Returns the complete sidebar as an ordered array of link text.
### Step 5: Confirm page identity
```
browser_cdp(
target_id="<target ID>",
method="Runtime.evaluate",
params={
expression: "document.title",
returnByValue: true
}
)
```
### Key differences from browser_console
| Aspect | `browser_console` | `browser_cdp` + `Runtime.evaluate` |
|---|---|---|
| Cap | Expression length | None (full function bodies ok) |
| Target | Current browser tab | Any target by ID |
| Shadow DOM | Limited | Limited (same as console) |
| Return size | Moderate | Large (substring approach) |
| Syntax errors | Reported inline | Fail silently on malformed arrow functions — use `(function(){...})()` not `()=>{...}` |
## Confirmed Case: RingLogix API Docs
URL: https://apidocs.ringlogix.com/
Status: Public, no login required
Content: ~186K characters of API documentation on page load
Structure: Sidebar with OAuth2, Agents, Agent Log, Answer Rule, Audio, CDR2, CDR Export, CDR Schedule, Call, Call Center Stats, Call Queue, Call Queue Stats, Subscriber, Device, Message, Emergency Address
~7,800+ elements in the DOM
## Confirmed Case: browser_console caveats
Two pitfalls observed:
1. `querySelector('nav')` returns null on Redoc pages — the sidebar renders as custom elements, not `<nav>`.
2. Arrow functions (`() => {...}`) with template literals can trigger `SyntaxError: Unexpected end of input` via `browser_console`. Use `(function(){...})()` syntax instead for complex expressions.
@@ -0,0 +1,207 @@
# RingLogix (NetSapiens/CPaaS) API Reference
White-label phone service provider (VoIPSimplicity backend). Docs at https://apidocs.ringlogix.com/ — public, no login required for browsing. Uses Redoc JS viewer.
## Base URL
```
https://api.ringlogix.com/pbx/v1/
```
## Authentication — OAuth2
**Endpoint:** `POST https://api.ringlogix.com/pbx/v1/oauth2/token/`
### Flow 1: Password grant (initial token)
```
POST /pbx/v1/oauth2/token/
Content-Type: application/x-www-form-urlencoded
grant_type=password
client_id=<from RingLogix>
client_secret=<from RingLogix>
username=<subscriber_login>
password=<subscriber_password>
```
### Flow 2: Refresh token
```
POST /pbx/v1/oauth2/token/
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
client_id=<from RingLogix>
client_secret=<from RingLogix>
refresh_token=<from prior auth>
```
### Success 200 Response
| Field | Type | Description |
|---|---|---|
| `access_token` | String | Bearer token |
| `expires_in` | Number | Seconds until expiry |
| `refresh_token` | String | For getting a new token |
| `domain` | String | Domain of the user |
| `scope` | String | Scope of access |
| `token_type` | String | Always "Bearer" |
| `legacy` | Boolean | In legacy API window? |
| `legacy_expires_days` | Number | Days remaining in legacy window |
| `recover` | Boolean | Was recovery email dispatched? |
**Important:** Client ID/Secret are obtained from RingLogix support — they are **separate** from PBX user credentials.
---
## Endpoint Catalog (42 sections, 238 endpoints)
All use POST. Routing via query string `?object=<object>&action=<action>`.
### Auth & Users
| Endpoint | Permission | Key Params |
|---|---|---|
| `?object=subscriber&action=count` | Reseller | `domain` (required) |
| `?object=subscriber&action=read` | Reseller | `domain`, `user`, `login`, `email`, `first_name`, `last_name`, `fields` |
| `?object=subscriber&action=list` | Basic User | `domain` |
### Device Provisioning
**`POST ?object=device&action=create`** — Permission: Reseller
| Param | Required | Description |
|---|---|---|
| `domain` | Yes | VoIPSimplicity domain |
| `device` | Yes | Name of the device |
| `user` | Yes | Owner (valid user extension) |
| `mac` | Yes | MAC address — hex only, 12 chars, no `:` or `-` |
| `model` | Yes | Phone model (query via Device/Model API) |
Also available: `count`, `read`, `update`, `delete` via the same object/action pattern.
### CDRs
| Endpoint | Description |
|---|---|
| `?object=cdr&action=read_by_domain` | Read CDRs by domain |
| `?object=cdr&action=read_by_user` | Read CDRs by user |
| `?object=cdr&action=read_by_group` | Read CDRs by group |
| `?object=cdr&action=report_by_domain` | Report CDRs by domain |
| `?object=cdr&action=read_by_id` | Read CDR by ID |
Also: CDR Export (create/read/download), CDR Schedule (create recurring exports), optimize/purge old CDRs.
### Call Control
| Section | Endpoints |
|---|---|
| Call | Count/Read/Report active calls, Answer, Disconnect, Make, Transfer, Park, Hold, Record, Playback |
| Call Queue | Create/Read/Update/Delete queues, Create queued calls |
| Call Queue Stats | Read queue stats |
| Call Center Stats | Agent log, DNIS stats, Queue stats, User stats |
### Phone Numbers & SMS
| Endpoint | Description |
|---|---|
| `?object=phone_number&action=count` | Count numbers in a dial plan |
| `?object=phone_number&action=read` | Read phone numbers |
| `?object=phone_number&action=update` | Update a phone number |
| `?object=sms_number&action=count` | Count SMS-capable numbers |
| `?object=sms_number&action=read` | Read SMS numbers |
| `?object=sms_number&action=update` | Update SMS number |
### Agents & Teams
| Section | Endpoints |
|---|---|
| Agent | Create/Count/Read/Update/Delete agents in a callqueue, Change status |
| Agent Log | Create/Read agent logs |
| Contact | Create/Count/Read/Update/Delete contacts |
| Department | Create/List departments |
| Presence | List presence in a domain |
### MAC Provisioning Endpoints
All POST to `https://api.ringlogix.com/pbx/v1/?object=mac&action=<action>`.
**Create:** `?object=mac&action=create` — Permission: OMP (Office Manager / Reseller / Super User)
| Param | Required | Description |
|---|---|---|
| `mac` | Yes | MAC hex only, 12 chars, no `-` `:` `.` |
| `domain` | Yes | Domain of new device |
| `model` | Yes | Phone model (query via Device_Model) |
| `transport` | No | NDP transport type |
| `server`, `last_pull`, `date_created` | No | Metadata |
| `device1..device8` | No | Device field references |
| `territory`, `notes` | No | Organization |
| `line1_ext..line2_ext` | No | Extension lines |
| `line1_enable..line8_enable` | No | Per-line enable flags |
| `line1_share..line8_share` | No | Line sharing |
| `overrides`, `dir_inc`, `presence` | No | NDP overrides |
Note: "Before using this module, the device should have already been instantiated."
**Read:** `?object=mac&action=read` — Permission: Reseller
| Param | Required | Description |
|---|---|---|
| `mac` | Yes | MAC to look up (hex, colons removed) |
| `extension` | Yes | Numerical string, searches lines with this extension |
| `checkExistance` | Yes | Boolean — check if MAC exists |
Response: mac, server, territory, dir_inc, presence, domain, model, device1-8, notes, line1-8_share, overrides, phone_ext, transport, fxs, sla, sidecar, resync, directory_support, user_agent, contact, registration_expires_time, registration_time
**Update/Delete/Count:** Same pattern via `?object=mac&action=update|delete|count`. Delete requires `mac` + `domain`. Count requires `domain` (optional: `territory`, `mac`, `mac_LIKE`, `model`).
**Device Model Query:** `?object=devicemodel&action=read` — Permission: Reseller — optional: `brand`, `model`, `portal_view`, `include_ndp_defs`, `ndp_syntax`
---
### Auto-Provisioning Flow (any phone, any source)
Phones from any vendor (retail, used, previous provider) work identically — MAC registration is the only per-phone step. The provisioning server URL is configured in the RingLogix portal UI, NOT via REST API.
1. **Factory reset** (used phones only) — wipe old provider config
2. **DHCP discovery** — phone boots, router serves DHCP options (156/66/160/43) pointing to provisioning server (configured once on your network gear)
3. **MAC registration**`POST ?object=mac&action=create` with MAC + model
4. **Device linking**`POST ?object=device&action=create` links MAC to subscriber extension
5. **Phone contacts NDP server** — RingLogix provisioning server matches MAC
6. **Config push** — Server pushes SIP credentials, extension, features. Phone auto-reboots configured
7. **Verify**`POST ?object=subscriber&action=read` checks account_status: active
DHCP Options (set once per network):
| Option | For | What it sets |
|---|---|---|
| 156 | Yealink / Poly | Provisioning server URL |
| 66 | Generic SIP | TFTP server address |
| 160 | Grandstream | HTTP provisioning URL |
| 43 | Cisco | Cisco provisioning |
---
## Common Header Pattern
All API calls after auth:
```
Authorization: Bearer <access_token>
```
## Key Observations
- **Not RESTful** — single base URL with `?object=&action=` routing
- **All POST** — parameters in form body
- **Reseller permission** required for provisioning operations
- **Basic User permission** sufficient for `subscriber&action=list`
- **Client ID/Secret** from RingLogix support (separate from PBX creds)
- **Postman collection** available from the docs site for testing
## Automation Opportunities
1. **Auto-provisioning**: Customer order → create subscriber → register MAC → link device → phone auto-provisioned on boot
2. **MAC-based provisioning**: Customer plugs in any phone — register MAC via API, phone picks up config from DHCP + NDP
3. **Second-hand phone handling**: Factory reset + MAC registration + device link = same flow as new phones
4. **CDR export automation**: Scheduled CDR export for billing
5. **DID management**: Phone number inventory, assignment, porting
6. **Customer lookup**: Query subscriber details by name/extension/domain
7. **DHCP config**: Option 156/66/160/43 set on customer's router once (not per-phone)