Open API 3.0 — Built for Full Portal-to-Portal Sync and Hudu Migration

Release

Overview

Open API 3.0 ships with release 4.6.27 in Q3 2026. It is the first IT Portal API designed as a complete tenant-migration surface — not just a read API with write endpoints bolted on, but a coherent set of capabilities that lets a program round-trip everything a tenant holds: objects, fields, files, folders, relationships, types, templates, credentials, and notes.

Two consumers proved the surface during development:

  • PortalSync — full portal-to-portal sync. A source tenant becomes a target tenant with every object kind, sub-entity, attached file, and audit-sensitive credential migrated end-to-end.
  • HuduImport — full migration from Hudu. Companies, articles, assets, passwords, attachments, and relationships flow into a new IT Portal tenant in a single run.

Both consumers run entirely on /p5/api/3.0/. There is no escape hatch into the database, no Classic ASP fallback, no manual reconciliation step.

Swagger (authoritative, gated): https://<your-host>/p5/api/3.0/docs/json/

Why this matters

Migration tooling fails when the API can't represent the source's state on the target. Past versions of the IT Portal API were rich on the read side and thin on the write side: list endpoints returned more fields than POST/PATCH accepted, sub-entities had no bulk routes, attached files were UI-only, and many writes round-tripped silently (sending a field on POST that the server didn't recognize succeeded with 200 OK but dropped the field).

3.0 closes those gaps. Every field a GET returns is accepted by POST and PATCH. Unknown fields are rejected loudly with unknownField, not silently dropped. Sub-entities have bulk endpoints. Files round-trip as binary. Credentials disclose plaintext only after a per-row audit insert. The API is the contract.

What ships in 3.0

Bulk everywhere — 50 items per call

Every kind has collection-level bulk POST and PATCH. Sub-entities (device IPs, management URLs, notes, drawings, sheets, interactions, relationships, credentials, fieldvalues) all have bulk variants. Standard 50-item cap, 207 Multi-Status envelope, per-item commit, index-correlated results.

On a 1,011-device demo tenant, PortalSync's main migration loop dropped from tens of thousands of round-trips to a few hundred batched calls.

Surface Bulk POST Bulk PATCH Bulk fetch
All 12 entity kinds yes yes yes
Sub-entities (ips, urls, notes) yes yes n/a
Drawings, sheets yes (25-cap) yes (25-cap) n/a
Relationships yes yes n/a
Credentials (additional + primary) yes yes yes (with audit)
Fieldvalues per kind yes yes yes
Types and KB categories yes yes n/a
Addresses, IP networks yes yes n/a

Tenant-wide list endpoints

Every list endpoint accepts an empty filter and returns the entire tenant's rows for that kind, with each row carrying its parent context. PortalSync no longer walks every parent kind individually to enumerate notes, files, sheets, or relationships — one call returns the whole set.

Supported tenant-wide on: drawings, sheets, interactions, relationships, notefiles. Each row in the response carries parent.itemType + parent.id so the consumer can bucket without tracking input scope.

Files and folders are first-class

Every major object kind exposes its folder tree and binary attachments through the API. Multipart uploads, raw-binary downloads, soft-delete, 409 safeguards when folders contain files. Note-image attachments use a GUID BlobID for cross-paste-safe references.

Agents and migration tools can finally round-trip attached documents, signed agreements, contact photos, device manuals, and KB references — not just the metadata.

Credentials disclosure with fail-closed audit

POST /api/3.0/credentials/additional/bulk-fetch and POST /api/3.0/credentials/{itemType}/bulk-fetch return plaintext passwords and 2FA codes — but only after writing one LogsPWAccess row per secret disclosed. Audit insert failure withholds plaintext for that row and returns 500 auditFailed; other rows in the batch continue. Sliding-window rate limit (10 requests per 60 seconds per API key) with Retry-After on 429.

PortalSync and HuduImport use these to migrate ~1,500 secrets per run in ~30 batched calls instead of one-at-a-time GETs.

Templates round-trip cleanly

The template tree — sections, fields, applies-to rules, typed field values — round-trips through GET and PATCH without data loss. A common pitfall was eliminated: PATCH /api/3.0/templates/{id}/ no longer accepts a sections array, which previously silently replaced the entire field tree on round-trip. PATCH /api/3.0/templates/{itemType}/{itemId}/ returns the templates that apply to a given parent with each field's filled-in value inlined.

Password fields surface as true/"" indicators only — plaintext requires the credentials endpoint with audit. No silent disclosure anywhere.

Natural-key lookup per kind

Each entity kind exposes a natural-key lookup endpoint that returns just the IDs matching a given name/hostname/serial. PortalSync uses this to answer "does this row already exist on the target?" before deciding INSERT vs SKIP — ceil(N / 50) round-trips instead of N.

Round-trip-clean field shapes

Field shapes that GET projects are exactly what POST and PATCH accept. Object-link fields (object, objectmultiselect) expose the linked entity's id + kind + name + url on GET and accept the same shape on writes. Gateway fields, foreign-id markers, and typed scalars all match.

When a field can't be represented as a primitive (e.g. legacy free-text values alongside a modern FK), the response shape carries both — and the write path accepts either, with deterministic precedence and stop-drift logic so the two columns can't diverge over a write cycle.

Scoped API keys + JWT bearer auth

API keys are scoped per resource, per HTTP method, and per company. A read-only PortalSync key can be issued with documents:GET, devices:GET, ... and nothing else; an import key for HuduImport gets the matching write methods.

Authentication is a key-for-JWT exchange:

POST /api/3.0/auth/token
Authorization: <raw API key>
→ { "access_token": "<jwt>", "expires_in": 3600 }

Subsequent calls use Authorization: Bearer <jwt>. The JWT is signed with a tenant-local secret and validates without a DB round-trip. Per-key scopes are encoded in the JWT and re-checked on every request.

Gated, machine-readable docs

GET /api/3.0/docs/json/ returns Swagger 2.0 — but the catalog is gated. Unauthenticated callers see only the /auth/token endpoint and a short set of instructions. After authenticating, the spec returns the endpoints and methods the calling key has scope for.

Point an AI agent at /api/3.0/docs/json/ with a valid key and it will discover exactly the surface it can act on, no more.

2.x parity sweep

Every field on the Classic ASP /api/2.x/ GET projection is present on /api/3.0/ — including the hardware specs (numberCpu, numberCores, memory, hardDiskInfo), warranty/lease dates, and per-kind scalars (KB expires, contact addressLine2, site timezone). Custom integrations that depended on 2.x's response shape work on 3.0 without code changes beyond the base path and auth swap.

Migration consumer #1 — PortalSync

PortalSync is the IT Portal team's tenant-to-tenant migration tool. Configure a source portal and a target portal, run PortalSync.exe --resync All, and the source tenant's state lands on the target tenant. Every object kind, sub-entity, file, folder, relationship, credential, and template value is migrated.

PortalSync uses only /api/3.0/. There is no 2.x fallback. The tool was developed alongside the API, and every "PortalSync needs X" turned into a 3.0 endpoint, validation tightening, or response-shape fix — visible in the API's gated docs CHANGELOG.

Migration consumer #2 — HuduImport

HuduImport ingests a Hudu export — companies, articles, assets, passwords, attachments, relationships — into an IT Portal tenant via /api/3.0/. The body-supplied parent-ref shape on credentials and the relationships bulk endpoints landed specifically to support Hudu's CSV shapes without per-row reshaping in the import tool.

A typical Hudu migration replaces ~1,500 round-trips for credentials alone with ~30 batched calls. Relationships drop from one-per-edge to 50-per-call.

Behavior fixes worth calling out

Change Impact
Unknown fields on POST/PATCH return 400 unknownField Past APIs silently accepted and dropped unknown fields. Migration callers now learn immediately if a field name is wrong.
PUT returns 405 Method Not Allowed with Use PATCH for partial updates. No silent writes.
?id__in=1,2,3 on every list endpoint Bulk-fetch known IDs in a single call.
Empty result is data.results: [], never null or 404 Consumers can iterate without null-guards.
Cursor pagination on every list endpoint Stable keyset pagination with modifiedSince for change polling.
Capability probes via 1-item bulk batch Future clients can detect bulk-endpoint availability without parsing the version string.

Migrating to 3.0

/api/3.0/ is a Portal5 evolution of the Classic ASP /api/2.x/ surface, not a wire-compatible upgrade. Callers porting from 2.x should expect:

  • Base path change from /api/2.x/ to /api/3.0/.
  • Auth change from raw-key header to key-for-JWT exchange and Bearer.
  • Docs are gated — fetch the spec with an authenticated request.
  • PUT is gone — use PATCH for partial updates.

The Classic ASP /api/2.x/ remains supported and unchanged. Migrate when the new capabilities (full file round-trip, bulk everywhere, scoped JWT, fail-closed credential audit) are worth the auth swap.

Availability

Open API 3.0 ships with release 4.6.27 in Q3 2026. Cloud customers receive access on the release day; on-premise upgrades follow the standard cadence.

PortalSync and HuduImport will be available for download on request.

Author Bio
Leslie Salvan

Leslie Salvan

Leslie Salvan is the Social Media Manager and SEO Lead at IT Portal, where she shapes the brand's digital presence and drives strategic growth across multiple platforms. With a strong focus on content clarity, search performance, and community engagement, she helps connect IT teams to smarter documentation solutions.

   Demo Live Demo