The Category object represents a software category or sub-category. It is used to classify software in the Public Catalog.
This object contains the following attributes:
id
string, core
(Read-only) An identifier for the category.
externalId
string
Identifier in the external system.
parentCategory
object
Represents the parent category. If null, then this is a top-level category.
name
string, core
A user-friendly name of the category.
icon
string, core
Icon to be shown on grids and info cards
description
string
A short description of the category
longDescription
string
A long description of the category
featured
bool
Indicates whether this product should be featured on the UI.
status
string, core
Indicates the status of the category. Allowed values are:
Draft
Published
Unpublished
Deleted
audit
object
(Read-only) Represents the audit object.
revision
integer, core
The entity's revision number.
{
"id": "CAT-1671-3887",
"externalId": "arK9uX45",
"name": "Development",
"parentCategory": {
"id": "CAT-1671-3886",
"name": "Productivity"
},
"description": "Software development tools",
"status": "Draft",
"revision": 2,
"audit": {
"created": {
"at": "2024-04-08T06:30:05.807Z",
"by": {
"id": "USR-2172-2499",
"revision": 1,
"name": "John User"
}
},
"updated": {
"at": "2024-05-16T09:17:36.406Z",
"by": {
"id": "TKN-3836-7769",
"revision": 2,
"name": "My token"
}
},
"deleted": {
"at": "2024-05-17T09:17:36.406Z",
"by": {
"id": "TKN-3836-7769",
"revision": 3,
"name": "My token"
}
}
}
}

The unique identifier of the category to be deleted.
No Content
No content
Forbidden
Not Found
Internal Server Error
No content
DELETE /public/v1/public-catalog/categories/{id} HTTP/1.1
Host: api.platform.softwareone.com
Accept: */*
No content
The category identifier.
Optional select expression.
OK
Not Found
GET /public/v1/public-catalog/categories/{id} HTTP/1.1
Host: api.platform.softwareone.com
Accept: */*
{
"id": "text",
"audit": {
"created": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"updated": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"published": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"unpublished": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
}
},
"$meta": {
"omitted": [
"text"
]
},
"name": "text",
"revision": 1,
"description": "text",
"parentCategory": {
"id": "text",
"name": "text",
"revision": 1,
"status": "Draft"
},
"status": "Draft"
}The unique identifier of the category to update.
OK
Bad Request
Not Found
PUT /public/v1/public-catalog/categories/{id} HTTP/1.1
Host: api.platform.softwareone.com
Content-Type: application/json
Accept: */*
Content-Length: 116
{
"name": "text",
"description": "text",
"optOutAllowed": true,
"note": "text",
"deleteAllowed": true,
"enabledByDefault": true
}{
"id": "text",
"audit": {
"created": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"updated": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"published": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"unpublished": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
}
},
"$meta": {
"omitted": [
"text"
]
},
"name": "text",
"revision": 1,
"description": "text",
"parentCategory": {
"id": "text",
"name": "text",
"revision": 1,
"status": "Draft"
},
"status": "Draft"
}The unique identifier of the category to unpublish.
OK
Bad Request
Forbidden
Not Found
POST /public/v1/public-catalog/categories/{id}/unpublish HTTP/1.1
Host: api.platform.softwareone.com
Accept: */*
{
"id": "text",
"audit": {
"created": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"updated": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"published": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"unpublished": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
}
},
"$meta": {
"omitted": [
"text"
]
},
"name": "text",
"revision": 1,
"description": "text",
"parentCategory": {
"id": "text",
"name": "text",
"revision": 1,
"status": "Draft"
},
"status": "Draft"
}The unique identifier of the category to publish.
OK
Bad Request
Forbidden
Not Found
POST /public/v1/public-catalog/categories/{id}/publish HTTP/1.1
Host: api.platform.softwareone.com
Accept: */*
{
"id": "text",
"audit": {
"created": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"updated": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"published": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"unpublished": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
}
},
"$meta": {
"omitted": [
"text"
]
},
"name": "text",
"revision": 1,
"description": "text",
"parentCategory": {
"id": "text",
"name": "text",
"revision": 1,
"status": "Draft"
},
"status": "Draft"
}Represents a request to create a new category in the public catalog. Contains the necessary properties for specifying category details.
Created
Bad Request
POST /public/v1/public-catalog/categories HTTP/1.1
Host: api.platform.softwareone.com
Content-Type: application/json
Accept: */*
Content-Length: 134
{
"name": "text",
"description": "text",
"parentCategory": {
"id": "text"
},
"vendorProfiles": [
{
"id": "text"
}
],
"productProfiles": [
{
"id": "text"
}
]
}{
"id": "text",
"audit": {
"created": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"updated": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"published": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"unpublished": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
}
},
"$meta": {
"omitted": [
"text"
]
},
"name": "text",
"revision": 1,
"description": "text",
"parentCategory": {
"id": "text",
"name": "text",
"revision": 1,
"status": "Draft"
},
"status": "Draft"
}Streaming read mode (MPT-Streaming: true) reads the whole filtered, sorted result set as a stream. Two obligations are mandatory for a correct read:
Verify completeness — compare the objects received with MPT-Item-Count. A mid-stream failure aborts the connection without completing the message, so a truncated body is the only failure signal.
Check $meta.deleted before ingesting — a record deleted, or moved out of scope, after the stream started arrives as an ID-only stub. Ingesting one as data overwrites a stored record. Soft-deleted records are ordinary records.
Stream the full result set instead of a page. Membership fixes at stream start, each record is emitted once, and MPT-Item-Count gives the exact count. Accept: application/jsonl for line-delimited output. A positive limit caps the stream, -1 or absent reads all; offset skips that many records of the requested order, so limit and offset together read one window. Each window is its own snapshot — consecutive windows are not a resumable export.
OK
Streamed and paged responses both answer 200. Only a streamed one carries the MPT-Streaming and MPT-Item-Count headers listed below.
application/jsonl: one object per line, no envelope, so the schema describes one line. A line is a record or an ID-only deleted stub (StreamedDeletedRecord) — check $meta.deleted before ingesting. Blank lines are keep-alives.
Streamed responses only, where it is true. Absent on a paged response.
Streamed responses only. Absent on a paged response. The exact object count — compare it with the number received.
Invalid RQL, or invalid paging. limit must be positive (caps the stream) or -1 / absent (reads all); offset must be a non-negative integer.
No content
No acceptable media type. application/jsonl without the MPT-Streaming header lands here.
No content
The result set exceeds the configured stream key cap. Nothing is written to the body.
No content
This resource's query service provides no streaming capability.
No content
GET /public/v1/public-catalog/categories HTTP/1.1
Host: api.platform.softwareone.com
Accept: */*
{
"$meta": {
"pagination": {
"offset": 1,
"limit": 1,
"total": 1
},
"omitted": [
"text"
]
},
"data": [
{
"id": "text",
"audit": {
"created": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"updated": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"published": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
},
"unpublished": {
"at": "2026-01-01T00:00:00.000Z",
"by": {
"id": "text",
"name": "text",
"icon": "text",
"revision": 1
}
}
},
"$meta": {
"omitted": [
"text"
]
},
"name": "text",
"revision": 1,
"description": "text",
"parentCategory": {
"id": "text",
"name": "text",
"revision": 1,
"status": "Draft"
},
"status": "Draft"
}
]
}Client timeouts. Set no total-request deadline — a stream lasts as long as its result set takes. Size the two limits that remain: allow at least 60s to the first byte, since nothing is on the wire while the key snapshot runs, and more than 30s between bytes, since idle gaps carry only keep-alive whitespace. One scalar timeout applied to connect and read alike trips on both.