Scope: the public Brandworkz API (the vendor's "Java API", documented as v1.6, v1.7 in production) used by the main Brandworkz platform, plus the small Brandworkz Essentials API of the free brand-kit product. Both are documented only as public Postman collections. API access is listed as an Enterprise-plan feature S12.
At a glance
format parameter or Accept header) S1. No GraphQL, SOAP or WebDAV foundhttps://api.brandworkz.com/getAPIURL?clientURL={tenant}.brandworkz.com (always on this global host, for staging or live, any region) returns api_url, client_id, version S1. Functional calls: {api_url}/v{api_version}/{client_id}/{endpoint}; the doc example returns api_url = https://us-api.brandworkz.com S1. OAuth endpoints are unversioned: {api_url}/oauth/token, {api_url}/oauth/authorize S1. Essentials API: https://main-api.brandworkz.com/… S3 S9getAssetMetadata is deprecated in favour of /metadata/asset S1. The vendor insists api_url, client_id and version must never be hard-coded because versions are retired S1 S5expires_in = 1,200 s in the documented example; renew with the refresh_token grant S1. Whether 1,200 s is a fixed value is not stated UnverifiedsimpleSearch from (zero-based offset) + size (default 50, max 500); folder listings start + numberOfResults or page + resultsPerPage; user messages limit + offset S1Authentication
Step 1 — discover the API host S1
- GET
https://api.brandworkz.com/getAPIURL?clientURL={tenant}.brandworkz.com(staging or live site URL) →{ "result": {code, message}, "data": { "api_url", "client_id", "version" } }. - Without
clientURLthe endpoint answers HTTP 400 S8. client_idhere is the site's database identifier (examplebrandworkz_{tenant}), not the OAuth client S1.
Step 2a — password grant (server-side integrations) S1
- POST
{api_url}/oauth/token, HTTP Basicconsumer_id:consumer_secret, form bodygrant_type=password&client_db={client_id}&username=…&password=…. - Response:
access_token(JWT),token_type: bearer,refresh_token,expires_in,scope, pluscdb(site DB),uid(user ID),sid,jti. - The user must be an existing user of the site; integrations therefore usually run as a dedicated Brandworkz user (inference Unverified).
Step 2b — authorization code (interactive; required with SAML SSO users) S1
- Redirect the browser to
{api_url}/oauth/authorize?clientDb={client_id}&response_type=code&client_id={consumer_id}&scope=read&redirect_uri=…. - The user logs in on the Brandworkz login form and clicks Authorize on an approval screen (Deny →
error=access_denied). - Exchange the code: POST
{api_url}/oauth/tokenwith Basic consumer credentials andgrant_type=authorization_code&client_db=…&code=…&redirect_uri=…(noteclient_dbhere vsclientDbin step 1).
- PKCE: not documented (Unknown). Client-credentials grant: not documented.
Step 3 — call the API with Authorization: Bearer {access_token}; refresh with grant_type=refresh_token S1.
Session login (legacy/UI): POST/login (with isIntegration=1) and GET/logout create and end a session for a user S1.
Essentials API: API keys are created and managed in Essentials Organisation Settings; all calls over HTTPS with Authorization: Bearer {API_KEY}; errors 403 Access Denied / 400 Bad Request / 500 S3. Unauthenticated calls get a JSON 403 access-error S9.
Core resources
Paths are relative to {api_url}/v{api_version}/{client_id}. Counts per Postman folder from the collection S1.
| Resource (folder, # requests) | Main endpoints | Notes |
|---|---|---|
| Assets (35) | GET/getAssets, GET/getCategoryAssets, POST/createUploadPath, POST/assemble, POST/importAsset, GET/moveAssets, GET/copyAssets, GET/deleteAssets, GET/setAssetsStatus, GET/relateAssets, GET/getAssetThumbnails, GET/getDownloadOriginalLinks, GET/getEmbedLink, GET/getAssetRendition, GET|POST /assets/permissions, GET/transforms, GET/getUsage, GET/assets/{assetIds}/dependencies | Many write operations are GETs with query parameters; older calls take sequential IDs, newer ones GUIDs. getAssetRendition only returns links for users with the CI HUB integration enabled |
| Metadata (8) | GET/metadata/asset, POST/saveMetadata, GET/getEmbeddedMetadata, GET/metadata/user, GET/metadata/user/{id}, GET/user/metasets, GET/getAlbumAssetMetadata, GET/getAssetMetadata (deprecated) | saveMetadata body: assetGuid (required), title, status, publish/expiry dates, languageCode, metasetRef, metadata{systemRef: value} |
| Search (6) | GET/simpleSearch, POST/search, GET/search/definition, POST/createSavedSearch, GET/getSavedSearches, GET/deleteSavedSearches | POST/search accepts a native Elasticsearch query; user permissions are injected server-side |
| Categories / folders (16) | GET/getCategoryInfo, GET/getSubCategories, GET/getCategoryListing, GET/createCategory (with a/b/c path creation), GET/moveCategory, GET/deleteCategory, GET/categories/permissions, GET/getModifiedResources, GET/getResourcesPage | Root category: getCategoryInfo?categoryID=0. Folders and CMS web pages are both categories |
| Albums (21) | GET/getAlbums, POST/createAlbum, POST/saveAlbum, POST/duplicateAlbum, GET/addAlbumAssets, GET/removeAlbumAssets, GET/getAlbumAssets, POST/shareAlbum, GET/getAlbumHistory, GET/getAlbumSentLogs | v1.7: album IDs become UUID4; createAlbumShortLink, getAlbumGlobalTransforms, getAlbumSentEntry removed; new getAlbumAssetDownloadOptions, getAssetDownloadOptions, updateAlbumAssetDownloadOptions S5 |
| Annotations (5) | POST/createAnnotation, GET/getAnnotations, GET/updateComment, GET/deleteAnnotation, GET/getWorkflowAnnotationPreviews | Tied to asset versions and workflow stages |
| CMS (20) | /cms/page/{categoryGuid} (POST/DELETE), /cms/page/duplicate/…, /cms/templates (CRUD), /cms/templateWidgets/…, /cms/widgetInstances/{guid} (GET/PUT), /cms/widget/codePreview… | Brand-guidelines pages, templates and widget ("block") instances |
| Navigation (11) | GET/treeNavigation, GET/albumTreeNavigation, GET/getBreadcrumb, /cms/masthead (CRUD + category assignment), POST/mastheadNavigation | Menus and breadcrumbs |
| Users & groups (26) | GET/users, POST/users/create, PUT/users/{userId}/edit, DELETE/users/{userId}/delete, GET/groups, GET/createGroup, GET/users/profile, GET/myStuff, POST/login, GET/logout, POST/users/password/validate | users/create sets login type (internal/SSO), groups and admin flags (sysadmin, users, groups, metadata, transforms, workflow, reports…) |
| Integration (11) | GET/assetInsert, GET|POST /integrations, PUT/integrations/{guid}, PUT/integrations/{guid}/parameters, POST/integrations/{guid}/enable|disable, GET/integrations/types, GET/integrations/templates, GET/integrations/{guid}/audit | assetInsert returns an embeddable search/browse picker (see below) |
| Renditions / transforms | GET/transforms, GET/getCategoryTransforms, GET/getAlbumTransforms, GET/getEmbedLink, GET/getAssetRendition | Transforms filterable by usage: CMSBRANDWORKZ, WEBEMBED, SITECORE, WORDPRESS, OFFICE, DRUPAL |
| Rights | Fixed fields assetStatus (0 hidden, 1 normal, 2 view-only), assetPublishDate, assetExpiryDate via saveMetadata; permission lookups /assets/permissions, /categories/permissions | No separate rights/licence object documented |
| Workflow, Web-to-Print | Not in the public collection | "Contact Brandworkz" for API services of other modules (Workflow, Web-to-Print) S1 |
| Essentials (5) | GET/brands, GET/brands/elements/colours, /fonts, /logos, /styles on main-api.brandworkz.com | Read-only brand-kit elements with on-/off-brand status filters S3 |
Data model
- Asset: identified by
assetGuid(version-independent, recommended), plus a human-friendly sequential serial number (assetSerialNumber/artwork_ID) andassetVersion;assetVersionGuididentifies a specific version. Older endpoints still take serial IDs, "likely to be retired" S1. - Shortcut: an alias of an asset in another folder, with its own ID/GUID (many endpoints take
assetIDsandshortcutIDs) S1. - Category: folder or CMS web page (a folder with a CMS template); search returns both as folders S1. Asset types: Image, Video, Audio, Document, Folder, Webpage, Editable template (W2P), User artwork S1; since v1.7 the type is read from
_source.assetType(_typeis always_doc) S5. - Metadata: metasets referenced by
metasetRef(systemRef), fields by systemRef; metadata is not version-specific S1. - Search hit: Elasticsearch-style
{_id (GUID), _source{title, description, extendedKeywords, thumbnailUrlCdn, objectURL, …}, _score};sourceFieldsselects returned fields (allincludes document full text — not for production) S1. - Response envelope:
{ "result": {code|status, message}, "data": {…} };result.status0 = success S1.
Search & querying
- GET
/simpleSearch?searchterm=…— keyword search, permission-aware, across all asset types by default; filterscategoryGUID(descendants),parentCategoryGUID(direct children — used to build a browse UI, sorted folders first then alphabetical),assetType(case-sensitive list),fileType(suffixes),sourceFields; pagingfrom/size(size ≤ 500) S1. - POST
/search— any valid Elasticsearch query (facets/aggregations possible), executed after the user's permissions are applied; requires knowledge of the index mapping (GET/search/definition) S1. - v1.7 change:
hits.totalbecame an object{value, relation}instead of an integer S5. - Deep pagination limit: Not public (Elasticsearch defaults would cap
from + size, but this is not documented Unverified).
Uploads & binaries
Three-step flow, binaries go directly to AWS S3 pre-signed URLs (S3 Transfer Acceleration hosts in the examples) S1:
- POST
/createUploadPathwithfileName,fileSize,categoryGuid, optionaluploadType(single-upload|multipart-upload),assetGuid(new version),isCustomThumbnail. ReturnsassetId,assetVersion,keyNameand either oneurlor an array ofurlswithuploadId,mainChunkSize,finalChunkSize,chunkNo. PUTthe file (or each chunk, keeping eachETag). Default chunking: files > 15 MB are split into 15 MB parts; chunk size grows if more than 200 parts would be needed. Single PUT theoretical maximum 5 GB; failures likely above 100–200 MB. Upload URLs expire after ~15 minutes (longer for big files). Postman cannot be used for the PUT (extra headers break the S3 signature).- Multipart only: POST
/assemblewithobjectKey,uploadId,parts[{partNumber, eTag}]. - POST
/importAssetwithcategoryGuid,keyName,originalFilename,assetId,assetVersion,fileSize; optionsassetGuid(new version),relativePath(auto-create sub-folders),MD5,duplicateAction(rename|addversion),approved=false+objectWorkflowStageID(enter a workflow),isCustomThumbnail.
- Response returns technical data (pixels, dpi, colour space, pages, duration, MD5 when de-duplication is on),
assetGuid,shortcutCreated/binaryIdenticalToGuid(de-duplication) andnameClash.result.status1 = error, 2 = not imported (e.g..exe) S1. - Indexing, thumbnails, full-text and colour extraction run asynchronously: ~30 s, up to 2 min for full text and colours; embedded metadata is extracted synchronously, so
saveMetadatacan be called immediately S1. - Downloads:
getDownloadOriginalLinks, transform/rendition links (getEmbedLink,getAssetRendition), thumbnails on a CDN (thumbnailUrlCdn, 320×320) S1; Smart Asset Embed links for web delivery S50.
Events & webhooks
- No public webhook or event subscription API. POST
/importAssetlists awebhookIdparameter without explanation S1 — purpose Unknown. - Change detection: GET
/getModifiedResources?modifiedStartDate=…&modifiedEndDate=…returns resources modified or deleted in the window S1. - Integration audit trail: GET
/integrations/{integrationGuid}/auditS1.
Limits & quirks
- Do not hard-code
api_url,client_idor the version: the vendor retires versions and moves hosts; always callgetAPIURLfirst S1 S5. - Two different "client IDs": the site DB id (
client_id/client_db/clientDb, fromgetAPIURL) vs the OAuth consumer ID — and parameter names differ between/oauth/authorizeand/oauth/tokenS1. - Many state-changing endpoints are GET requests (e.g.
deleteAssets,moveAssets,createCategory,deleteAlbum) S1. - Error codes: 401/1 authentication required, 502/2 service not available, 422/3 argument error, 500/4 configuration error;
result.status5 "Service endpoint call failed" with a root cause S1. Choice fields reject unknown options with HTTP 500; duplicate asset titles in a folder return 400 with a suggested name S1. sourceFields=allcan return multi-megabyte responses (document full text) S1.- Rate limits, quotas and concurrency limits: Not public.
- Unverified Documentation drift: the public collection (v1.6, 2023) predates the v1.7 changes (2025-01-18) and still documents removed album endpoints and the old
_typesemantics S1 S5.
SDKs, tools & code samples
| Library / tool | Language | Maintainer | Status |
|---|---|---|---|
| bwkz/assetInsert-integration-examples | JavaScript (jQuery; ES6 + Webpack) | Brandworkz | Examples for embedding the /assetInsert picker; last push 2019-03-28 S6 |
| "Run in Postman" button on the docs | Postman | Brandworkz | Requires a Postman account; environment variables api_url, client_id, api_version, access_token suggested S1 |
/assetInsertreturns a complete HTML/React picker (keyword search, facets, folder browsing, detail view, download options, single/multi-select) to embed in a pop-up or iframe; it calls back the host app with JSON describing the selected files — the vendor's preferred route for CMS/e-commerce "insert asset" integrations S1 S6.- No official SDK on npm or PyPI (searched 2026-10-01); no community SDK found (Unknown).
Changelog of the API
| Date | Change |
|---|---|
| 2025-01-18 | v1.7 in production (staging from 2024-12-20): hits.total becomes {value, relation}, _type always _doc (use _source.assetType), album IDs UUID4, addAlbumAssets adds permitted transforms, getAlbumAssets returns transforms per asset; removed createAlbumShortLink, getAlbumGlobalTransforms, getAlbumSentEntry; new album/asset download-option endpoints S5 |
| 2023-03-29 | Current public Postman documentation "Brandworkz API (v1.6)" published S1 |
| 2022-08-03 | "Brandworkz Essentials API" documentation published S3 |
| 2019-02 | assetInsert integration examples published on GitHub S6 |
| Undated | getAssetMetadata deprecated in favour of GET/metadata/asset S1 |